Memory leak,copy constructor,assign operator - c++

Everthing is in the code
Here is code. Constructor's.
Polynomial::Polynomial()
{
base=0;
Coefficients=new int [base+1];
Coefficients[0]=0;
}
Basically creates Poly equals to 0;
Polynomial::Polynomial(const unsigned int length,const int* table)
{
base=length;
bool a=false;
for(int i=length;i>=0;i--)
{
if(table[i]==1&&a==false)
{
a=true;
Coefficients=new int[base+1];
};
if(table[i]==0&&a==false)
{
base--;
};
if(a==true)
Coefficients[i]=table[i];
}
}
Here we create Poly with given length(it can be higher than Poly base)
I think so far everything is ok.
Now copy constructor:
Polynomial::Polynomial(const Polynomial& P)
{
base = P.base;
Coefficients=new int[base+1];
for(unsigned int i=0; i<base+1;i++)
{
Coefficients[i]=P.Coefficients[i];
}
}
And assign operator:
Polynomial& Polynomial::operator =(const Polynomial &P)
{
base=P.base;
for(unsigned int i=0;i<P.base+1;i++)
Coefficients[i]= P.Coefficients[i];
return *this;
}
I think there is smth wrong with this because when i overloaded + operator
And created Polynomial a,u,v;
When i typed a=v+u;
Sometimes i had garbage values and " Process returned -1073741819 (0xC0000005)"
I've read some about switch/copy but is there simple solution in my code that I am missing on?
Polynomial operator +(const Polynomial& a,const Polynomial& b)
{
Polynomial c;
if(a.base>=b.base)
c.base=a.base;
else
c.base=b.base;
c.Coefficients=new int[c.base+1];
for(unsigned int i=0;i<c.base+1;i++)
{
c.Coefficients[i]=0;
};
for(unsigned int i=0;i<b.base+1;i++)
{
c.Coefficients[i]=b.Coefficients[i];
};
for(unsigned int i=0;i<a.base+1;i++)
{
c.Coefficients[i]+=a.Coefficients[i];
}
return c;
}
Here is destructor
Polynomial::~Polynomial()
{
delete []Coefficients;
}
+= operator
Polynomial& Polynomial::operator +=(const Polynomial& a)
{
if(a.base>base)
{
base=a.base;
Coefficients = (int*)realloc(Coefficients, (base+1)*sizeof(int));
for(unsigned int i=0;i<base+1;i++)
{
if(Coefficients[i]!=0&&Coefficients[i]!=1)
{
Coefficients[i]=0;
}
Coefficients[i]+=a.Coefficients[i];
}
}
if(a.base<=base)
{
for(unsigned int i=0;i<a.base+1;i++)
{
Coefficients[i]+=a.Coefficients[i];
}
}
return *this;
}

Related

NULL data stored by overloaded istream

This is part of my polynomial.cpp to get terms by overloading istream
void Newterm(float coef, int deg) {
if (terms == capacity) {
capacity *= 2;
Term* tmp = new Term[capacity];
copy(termArray, termArray + terms, tmp);
termArray = tmp;
delete[] tmp;
}
termArray[terms].degree = deg;
termArray[terms++].coef = coef;
}
friend istream& operator >> (istream& is, Polynomial& pl) {
cout << "number of terms : ";
int t; is >> t;
cout << endl;
float coeff;
int degree;
for (int i = 0; i < t;i++) {
cout << i + 1 << "'s term: ";
is >> coeff >> degree;
pl.Newterm(coeff, degree);
}
return is;
};
of course, i tried to figure out whaaat made this result..
tried:
removing 'for' loop
this actually worked.. but it only works when terms=1
firstly creating term and input data
Newterm(0,0);
is>>pl.termArray[i].coef>>pl.termArray[i].degree;
it couldn't fix anything...
so i think it has to do with loops..
but whyyyy?
Using std::vector instead of doing your own memory managment
(why reinvent the wheel if there is a tested solution in the standard library)
#include <iostream>
#include <vector>
struct Term final
{
Term() = default;
~Term() = default;
Term(int d, double c) :
degree{ d },
coef{ c }
{
}
int degree{ 0 };
double coef{ 1.0 };
};
class Polynomial final
{
public:
Polynomial() = default;
~Polynomial() = default;
explicit Polynomial(const std::initializer_list<Term> terms) :
m_terms{ terms }
{
}
void add(const Term& term)
{
m_terms.push_back(term);
}
private:
std::vector<Term> m_terms;
};
std::istream& operator>>(std::istream& is, Polynomial& polynomial)
{
std::size_t n{ 0 }; // indices are not ints the can't be < 0
is >> n;
for (std::size_t i = 0; i < n; ++i)
{
Term term{};
is >> term.coef;
is >> term.degree;
polynomial.add(term);
}
return is;
}
int main()
{
// to show you that std::vector can handle all the memory managment for you
// constructor with an initializer list that adds 3 terms
// that's also why the Term has a constructor, it is to make it work with
// initializer list
Polynomial p{ { 1,2.0 }, { 2,4.0 }, { 1,-1.0 } };
}

Strange copy constructor and destructor error

I have a class and i keep getting some error from the destructor.
This is the clas:
#pragma once
class Number
{
int bas;
char* val;
public:
Number(const char* value, int base);
Number(const Number& x);
~Number();
void SwitchBase(int newBase);
void Print();
int GetDigitsCount();
int GetBase();
};
This is the cpp file:
#include "Number.h"
#include <iostream>
Number::Number(const char* value, int base)
{
int a = -1;
do
{
a++;
} while (value[a] != '\0');
val = new char[a + 1];
for (int i = 0; i <= a; i++)
val[i] = value[i];
bas = base;
}
Number::Number(const Number& x)
{
int a = -1;
bas = x.bas;
do
{
a++;
} while (x.val[a] != '\0');
delete[]val;
val = new char[a + 1];
int i;
for (i = 0; i <= a; i++)
val[i] = x.val[i];
}
Number::~Number()
{
delete[]val;
}
void Number::Print()
{
std::cout << "Numarul este: " << val<< std::endl << "Baza este: " << bas<<std::endl;
}
int Number:: GetDigitsCount()
{
int l = 0;
do
{
l++;
} while (val[l] != '\0');
return l;
}
This is the main:
int main()
{
Number x("123", 10),y("111",10),z("0",10);
z = y;
z.Print();
}
I keep getting this error:
Invalid address specified to RtlValidateHeap( 010C0000, 010C8DD8 )
If i do this change in main it works properly but it is not really what I want...
int main()
{
Number x("123", 10),y("111",10);
Number z = y;
z.Print();
}
How can I solve this? I can't figure it out...
Your Number class is missing an assignment operator. Since you use the assignment operator in main the default assignment operator will cause a double delete when you exit main and this explains the error.
It also explains why the error goes away when you change main to use the copy constructor instead of the assignment operator.
You should look at the copy and swap idiom to show how to easily and efficiently implement copy constructors and assignment operators.
Alternatively you could also use std::string instead of manually allocating memory. This would eliminate the need to write a destructor, copy constructor and assignment operator. That's the best solution.
This is an example of how code may look like using std::string:
#include <iostream>
#include <string>
class Number
{
int bas;
std::string val;
public:
Number(std::string, int base);
Number(const Number& number);
Number& operator= (const Number& number);
~Number()=default;
void Print();
int GetDigitsCount();
};
Number::Number(std::string value, int base)
{
val=value;
bas=base;
}
Number::Number(const Number& number)
{
val=number.val;
bas=number.bas;
}
Number& Number::operator= (const Number& number)
{
val=number.val;
bas=number.bas;
return *this;
}
void Number::Print()
{
std::cout << "Numarul este: " << val<< std::endl << "Baza este: " << bas<<std::endl;
}
int Number:: GetDigitsCount()
{
return val.size();
}
int main()
{
Number x("123", 10),y("111",10),z("0",10);
Number k(y);
k.Print();
}

Efficent Sum and Assignment operator overloading in C++

Hi I'm implementing a matrix class in c++
I know that there are great libraries that do that like opencv but I need to do that myself.
For example if I implement the sum I can do like this
class Mat{
public:
double* data;
int rows,cols;
Mat(int r,int c):rows(r),cols(c){
data = new double[r*c];
}
};
void Sum(Mat& A,Mat& B,Mat& C){
for (int i = 0; i < A.rows*A.cols; ++i){
C.data[i] = A.data[i]+B.data[i];
}
}
int main(){
//Allocate Matrices
Mat A(300,300);
Mat B(300,300);
Mat C(300,300);
//do the sum
sum(A,B,C);
}
I would like to get something more readable like this but without losing efficiency
C = A + B
This way C is reallocated every time and I don't want that
Thank you for your time
Delay the calculation.
class MatAccess {
friend class Mat;
friend class MatOpAdd;
virtual double operator[](int index) const = 0;
};
class MatOpAdd: public MatAccess {
friend class Mat;
private:
const MatAccess& left;
const MatAccess& right;
MatOpAdd(const MatAccess& left, const MatAccess& right):
left(left), right(right) {}
double operator[](int index) const {
return left[index] + right[index];
}
};
class Mat: public MatAccess{
public:
double* data;
int rows,cols;
Mat(int r,int c):rows(r),cols(c){
data = new double[r*c];
}
MatOpAdd operator +(const MatAccess& other) {
return MatOpAdd(*this, other);
}
const Mat& operator = (const MatAccess& other) {
for(int i = 0; i < rows*cols; ++i) {
data[i] = other[i];
}
return *this;
}
private:
double operator[](int index) const {
return data[index];
}
double& operator[](int index) {
return data[index];
}
};
int main(){
//Allocate Matrices
Mat A(300,300);
Mat B(300,300);
Mat C(300,300);
//do the sum
C = A + B;
}
Now the '+' calculation will be done in the "operator="
Things I would change:
MatAccess should include the dimensions (rows,cols).
Mat adding constructors and operator= or make it not copyable
Mat::operator+ and Mat::operator= check for equal rows,col
delete memory when not used anymore or
use std::vector for simpler memory managment.
Created a bigger example here: https://gist.github.com/KoKuToru/1d23af4bbf0b2bc89893

Using vector in C++ to calculate big integer

I've coded a program to practice using header and class.
So the project have three files.
main.cpp BigInteger.h BigInteger.cpp
I called class "BigInteger" in main.cpp
when I read the string from main,it shows correctly.
But when I using +,-,* operator.
It shows me the answer but add a '0' in front of the answer.
the following is my code
//main.cpp
#include "BigInteger.h"
int main() {
BigInteger a("-1234567890");
BigInteger b("234567891");
BigInteger ans1, ans2, ans3, ans4;
BigInteger c(a), d;
ans1 = a + b;
ans2 = a - c;
ans3 = c - b;
ans4 = a*b;
cout<<"a="; a.print();
cout<<"b="; b.print();
cout<<"c="; c.print();
cout<<"d="; d.print();
cout<<"a+b="; ans1.print();
cout<<"a-c="; ans2.print();
cout<<"c-b="; ans3.print();
cout<<"a*b="; ans4.print();
}
//header
#include <iostream>
#include <vector>
#include <string>
#define MAX_SIZE 80
using namespace std;
static const int ROWS=4, COLS=4;
class BigInteger{
private:
vector <int> digits;
bool positive; //正負數,0的正負設為正
void adding(const vector <int> &x,const vector <int> &y, vector <int> &z);
void subing(const vector <int> &x ,const vector <int> &y, vector <int> &z);
bool max(const vector <int> & x,const vector <int> & y);
void Reverse( vector <int> & r);
public:
BigInteger(string s);
BigInteger();
BigInteger(const BigInteger & r);
BigInteger & operator =(const BigInteger & r);
BigInteger operator +(const BigInteger & r);
BigInteger operator -(const BigInteger & r);
BigInteger operator *(const BigInteger & r);
void print();
};
//BigInteger.cpp
#include "BigInteger.h"
#include "math.h"
BigInteger::BigInteger(string s)
{
for(int i=0;i<s.size();i++) {
if(s[i]!='-') {
digits.push_back(s[i]-'0');
}
}
if(s[0]=='-') positive=true;
else positive=false;
}
BigInteger::BigInteger()
{
digits.push_back(0);
positive=false;
}
BigInteger::BigInteger(const BigInteger & x){
for(int i=0;i<x.digits.size();i++)
digits.push_back(x.digits[i]);
positive=x.positive;
}
BigInteger & BigInteger::operator =(const BigInteger & x){
for(int i=0;i<x.digits.size();i++)
digits.push_back(x.digits[i]);
positive=x.positive;
return (*this);
}
BigInteger BigInteger::operator +(const BigInteger & x){
BigInteger answer;
answer.digits.clear();
bool pre; //if the front one is bigger return true.
if(positive==x.positive){
answer.positive=positive;
adding(digits,x.digits,answer.digits);
}
else{
pre=max(digits,x.digits);
if(pre) subing(digits,x.digits,answer.digits);
else subing(x.digits,digits,answer.digits);
answer.positive=false;
if(positive&&pre) answer.positive=true;
if((!positive)&&(!pre)) answer.positive=true;
}
return answer;
}
BigInteger BigInteger::operator -(const BigInteger & x){
BigInteger answer;
answer.digits.clear();
bool pre=max(digits,x.digits);
if(positive!=x.positive){
answer.positive=true;
if(pre) adding(digits,x.digits,answer.digits);
else adding(x.digits,digits,answer.digits);
}
else if(positive&&x.positive){
if(pre) {
subing(digits,x.digits,answer.digits);
answer.positive=true;}
else {
subing(x.digits,digits,answer.digits);
answer.positive=false;}
}
else {
if(pre){
answer.positive=false;
subing(digits,x.digits,answer.digits);}
else {
answer.positive=true;
subing(x.digits,digits,answer.digits);
}
}
return answer;
}
BigInteger BigInteger::operator *(const BigInteger & x){
BigInteger answer;
long long int a=0,b=0,ans=0;
int ten=1;
answer.digits.clear();
for(int i=digits.size()-1;i>=0;i--)
{
a+=digits[i]*ten;
ten*=10;
}
ten=1;
for(int i=x.digits.size()-1;i>=0;i--)
{
b+=x.digits[i]*ten;
ten*=10;
}
ans=a*b;
if(positive==x.positive) answer.positive=false;
else answer.positive=true;
while(ans>0)
{
answer.digits.push_back(ans%10);
ans=ans/10;
}
Reverse(answer.digits); //cause i use push_back ,it will be backwards
return answer;
}
void BigInteger::adding(const vector <int> & x,const vector <int> & y, vector <int> & z)
{
long long int a=0,b=0,ans=0;
BigInteger answer;
int ten=1;
answer.digits.clear();
for(int i=x.size()-1;i>=0;i--)
{
a+=x[i]*ten;
ten*=10;
}
ten=1;
for(int i=y.size()-1;i>=0;i--)
{
b+=y[i]*ten;
ten*=10;
}
ans=a+b;
while(ans>0)
{
z.push_back(ans%10);
ans=ans/10;
}
Reverse(z); //cause i use push_back ,it will be backwards
}
void BigInteger::subing(const vector <int> & x,const vector <int> & y, vector <int> & z){
long long int a=0,b=0,ans=0;
BigInteger answer;
int ten=1;
answer.digits.clear();
for(int i=x.size()-1;i>=0;i--)
{
a+=x[i]*ten;
ten*=10;
}
ten=1;
for(int i=y.size()-1;i>=0;i--)
{
b+=y[i]*ten;
ten*=10;
}
ans=a-b;
while(ans>0){
z.push_back(ans%10);
ans/=10;
}
Reverse(z); //cause i use push_back ,it will be backwards
}
bool BigInteger::max(const vector <int> & x,const vector <int> & y){
if(x.size()>y.size())
return true;
else return false;
}
void BigInteger::Reverse(vector <int> & z) {
int temp,j=z.size()-1;
for(int i=0;i<z.size()/2;i++)
{
temp=z[i];
z[i]=z[j];
z[j]=temp;
j-=1;
}
}
void BigInteger::print()
{
if(positive==true)
cout<<"-";
else
cout<<"";
//cout<<digits[0]<<endl;
for(int i=0;i<digits.size();i++){
cout<<digits[i];
}
cout<<endl;
// cout<<digits[6]<<digits[7]<<digits[8]<<digits[9]<<endl;
}
void BigInteger::print()
{
if(positive==true)
cout<<"-";
else
cout<<"";
//cout<<digits[0]<<endl;
for(int i=0;i<digits.size();i++){
cout<<digits[i];
}
cout<<endl;
// cout<<digits[6]<<digits[7]<<digits[8]<<digits[9]<<endl;
}
You can write like this
void BigInteger::print()
{
if(positive==true)
cout<<"-";
else
cout<<"";
//cout<<digits[0]<<endl;
bool not_zero_detect=false;
for(int i=0;i<digits.size();i++){
if(digits.size()!=1&& digits[i]==0 && not_zero_detect==false)
{
digits[i]=digits[i];
}
else
{
not_zero_detect=true;
cout<<digits[i];
}
}
cout<<endl;
// cout<<digits[6]<<digits[7]<<digits[8]<<digits[9]<<endl;
}
use bool like "not_zero_detect" to check whether it has zero in front of the number or not
PS: Thanks for sharing your homework :-)

Implementation of Polygon class

I am writing a program that contains three classes: They are point, line and polygon. I have written the first two, but I am having trouble with the last one.
This class has to have two constructors, one of them builds an object with a point (tip of polygon) and another one builds it with a line. These functions have to be as follows:
polygon(point** arr,int size) and polygon(line** arr,int size).
I don't know why point and line are pointer to pointer? What are the attributes of the polygon class and how can I write polygon's constructor?
class point
{
private:
int first;
int second;
public:
point(void);
point (int x,int y);
point (const point& other);
int getX();
int getY();
int distance(point* other);//distance of two point
line* Line(point*);//build a line with two point
polygon* triangle(point*,point*);//build a triangle with three point
~point(void);
};
point::point(void)
{
first=0;
second=0;
}
point::point (int x,int y)
{
first=x;
second=y;
}
point::point(const point& other)
{
first=other.first;
second=other.second;
}
int point::gha(int a)
{
if(a>=0)
return a;
else
return -a;
}
int point::pow(int a)
{
return a*a;
}
int point::getX(){return first;}
int point::getY(){return second;}
int point::distance(point* other)
{
int d= sqrt((pow(first-other->first))+(pow(second-other->second)));
return d;
}
line* point::Line(point* other)
{
line l(this,other);
return &l;
}
polygon* point::triangle(point*,point*){
}
point::~point(void)
{
}
////////////////////////////
class line
{
private:
int m;
int c;
public:
line(void);
line(point*,point*);
line(int ,point*);
bool isParallel(line*);
bool isPrependicular(line*);
point* intersection(line*);
line* parallel(point*);
polygon* triangle(line*,line*);
~line(void);
};
line::line(void)
{
m=1;
c=0;
}
line::line(point* a,point* b)
{
m=((a->getY())-b->getY())/(a->getX()-b->getX());
c=a->getY()-(m*(a->getX()));
}
line::line(int dip,point* a)
{
m=dip;
c=a->getY()-(dip*(a->getX()));
}
bool line:: isParallel(line* other)
{
if(m==other->m)
return true;
else
return false;
}
bool line::isPrependicular(line* other)
{
if((m*other->m)==1 || (m*other->m)==-1)
return true;
else
return false;
}
point* line::intersection(line* other)
{
int x=(other->c-c)/(m-other->m);
int y=(m*x)+c;
point p (x,y);
return &p;
}
line* line::parallel(point* other)
{
line l(m,other);
return &l;
}
line::~line(void)
{
}
///////////////////////////////////
class polygon
{
private:
int count;
point* tip;
line* l;
public:
polygon(void);
polygon(point** arr,int size);
polygon(line** arr,int size);
bool isTriangle();
bool isSquare();
~polygon(void);
};