Here is my code, why is it showing segmentation fault? Can someone correct my mult4 function... I know that problem is mult4 and i am not sure is function mult4 is correct solution for polynomial recursively multiplication...
#include <iostream>
#include <cstdlib>
using namespace std;
class Polynomial
{
public:
Polynomial()
{
deg=0;
coeff = new float[deg+1];
coeff[0]=0;
}
Polynomial(int n)
{
deg = n;
coeff = new float[deg+1];
for(int i = 0; i<=deg;i++)
coeff[i] = rand()/(float)RAND_MAX;
}
Polynomial(float *array, int n)
{
deg=n;
coeff=array;
}
Polynomial(const Polynomial& P)
{
deg = P.deg;
coeff = new float[deg+1];
for(int i=0;i<=deg;i++) coeff[i] = P.coeff[i];
}
~Polynomial()
{
delete []coeff;
}
Polynomial operator+(const Polynomial& P) const;
Polynomial operator-(const Polynomial& P) const
{
int i;
Polynomial c;
if(deg>=P.deg)
{
c.deg=deg;
for(i=deg;i>=0;i--)
c.coeff[i]=coeff[i];
for(i=P.deg;i>=0;i--)
c.coeff[i]=c.coeff[i]-P.coeff[i];
}
else
{
c.deg=P.deg;
for(i=P.deg;i>=0;i--)
c.coeff[i]=-P.coeff[i];
for(i=deg;i>=0;i--)
c.coeff[i]=c.coeff[i]+coeff[i];
}
return c;
}
Polynomial& operator=(const Polynomial& P)
{
if (this!=&P)
{
delete [] coeff;
deg = P.deg;
coeff = new float[deg+1];
for(int i=deg;i>=0;i--) coeff[i] = P.coeff[i];
}
return (*this);
}
float operator[](float x) // evaluation of polynomial
{
float rez=0;
for(int i=deg;i>=0;i--)
rez=rez*x+coeff[i];
return rez;
}
int degree() const
{
return deg;
}
public:
float *coeff; // array- representation of polynomial
int deg; //degree of polynomial
friend ostream& operator<<(ostream &out, const Polynomial& P) //overload operatpr<<
{
for ( int i =P.deg; i >= 0; i-- )
{
out << P.coeff[i] << "x^" << i << " ";
if(i>=1)
{
if(P.coeff[i-1]>0) out<<"+";
}
}
out << endl;
return out;
}
};
Polynomial Polynomial::operator+(const Polynomial& P) const
{
int i;
Polynomial c;
if(deg>=P.deg)
{
c.deg=deg;
for(i=deg;i>=0;i--)
c.coeff[i]=coeff[i];
for(i=P.deg;i>=0;i--)
c.coeff[i]=c.coeff[i]+P.coeff[i];
}
else
{
c.deg=P.deg;
for(i=P.deg;i>=0;i--)
c.coeff[i]=P.coeff[i];
for(i=deg;i>=0;i--)
c.coeff[i]=c.coeff[i]+coeff[i];
}
return c;
}
Polynomial shift(Polynomial A, int x)
{
Polynomial c(A.deg+x);
int k=0;
for(int i=c.deg;i>=0;i--)
c.coeff[i]=0;
for(int i=A.deg;i>=0;i--)
{
c.coeff[c.deg-k]=A.coeff[i];
k++;
}
return c;
}
Polynomial mult4( Polynomial P, Polynomial Q)
{
if(P.deg==1)
{
Polynomial qw(2);
qw.coeff[0]=P.coeff[0]*Q.coeff[0];
qw.coeff[2]=P.coeff[1]*Q.coeff[1];
qw.coeff[1]=P.coeff[1]*Q.coeff[0]+Q.coeff[1]*P.coeff[0];
return qw;
}
else
{
Polynomial p1(((P.deg)/2)-1);
Polynomial p2(P.deg-(P.deg)/2);
Polynomial q1(((Q.deg)/2)-1);
Polynomial q2(Q.deg-(Q.deg)/2);
int k=0;
for(int i=p1.deg;i>=0;i--)
{
p1.coeff[i]=P.coeff[i];
}
for(int i=p2.deg;i>=0;i--)
{
p2.coeff[i]=P.coeff[P.deg-k];
k++;
}
for(int i=q1.deg;i>=0;i--)
{
q1.coeff[i]=Q.coeff[i];
}
k=0;
for(int i=q2.deg;i>=0;i--)
{
q2.coeff[i]=Q.coeff[P.deg-k];
k++;
}
Polynomial t1,t2,t3;
t1=mult4(p1+p2,q1+q2);
t2=mult4(p1,q1);
t3=mult4(p2,q2);
return(t2+shift(t1-t2-t3,P.deg/2)+shift(t3,2*(P.deg/2)));
}
}
int main()
{
float *p=new float[4];
for(int i=3;i>=0;i--)
p[i]=-1.1+i;
float *k=new float[5];
for(int i=4;i>=0;i--)
k[i]=-1.2+i;
Polynomial P(p,3);
Polynomial K(k,4);
cout<<mult4(P,K);
return 0;
}
You have several errors in your code.
You need a copy constructor. Familiarize yourself with The Rule Of Three.
There are many lines where you set the deg of a Polynomial but don't allocate memory for coeff. For example, in shift, you have:
Polynomial shift(Polynomial A, float x)
{
Polynomial c;
int k=0;
c.deg=A.deg+x;
for(int i=c.deg;i>=0;i--)
c.coeff[i]=0;
What you need is:
Polynomial shift(Polynomial A, float x)
{
// Polynomial c(A.deg+x);
// Not sure why you whether c.deg should be A.deg+x or just A.deg.
Polynomial c(A.deg);
int k=0;
for(int i=c.deg;i>=0;i--)
c.coeff[i]=0;
In the operator= function, you are changing the index incorrectly. In stead of using:
for(int i=deg;i>=0;i++) coeff[i] = P.coeff[i];
you need to use:
for(int i=deg;i>=0;i--) coeff[i] = P.coeff[i];
// ^^ Decrement, not increment
In mult4, your use of
p1.deg=((P.deg)/2)-1;
seems flawed. What happens when P.deg/2 is equal to 0? Perhaps you need to use:
p1.deg=(P.deg)/2;
Setting of q1.deg must be similarly updated.
I might have missed other errors.
Related
I am trying to run my code from past few days but these errors are just not going away. The code is running smoothly in Code blocks but generating errors in Linux.
The errors are:
Matrix.h:14:20: error: expected ‘)’ before ‘rows’
Matrix(std::size_t rows, std::size_t cols, double initValue)
^~~~
Matrix.h:234:2: error: expected ‘}’ at end of input
};
^
Matrix.h:10:20: error: expected unqualified-id at end of input
double *p = nullptr;
I have already checked the semi colons and brackets and they seem to be all right.
My code is
#ifndef MATRIX_H
#define MATRIX_H
class Matrix
{
private:
int r, c, z;
double *p = nullptr;
public:
Matrix(std::size_t rows, std::size_t cols, double initValue)
{
r = rows;
c = cols;
z = r*c;
p = new double [z];
for(int i=0; i<z; ++i)
{
p[i]=initValue;
//cout<< p[i];
}
}
~Matrix()
{
delete [] p;
}
Matrix(const Matrix& m1) : r(m1.r), c(m1.c), z(r*c)
{
p = new double [z];
for (int i=0; i<z; ++i)
{
p[i]=m1.p[i];
}
}
//= operator overloading
Matrix& operator=(const Matrix& m1)
{
if (*this == m1)
return *this;
else
{
r= m1.r;
c=m1.c;
z=r*c;
delete[] p;
p=nullptr;
p= new double[m1.z];
for(int i=0;i<z;++i)
{
p[i]=m1.p[i];
}
return *this;
}
}
double& operator()(std::size_t i, std::size_t j)
{
return p[i*c+j];
}
const double& operator()(std::size_t i, std::size_t j) const
{
return p[i*c+j];
}
bool operator ==(const Matrix& m1) const
{
if(r==m1.r && c==m1.c)
{
for(int i=0;i<z;++i)
{
if (p[i]!=m1.p[i])
{
return false;
}
}
}
else if(r!=m1.r || c!=m1.c)
{
return false;
}
return true;
}
bool operator !=(const Matrix& m1) const
{
if( r!=m1.r || c!=m1.c)
{
return true;
}
for(int i=0;i<m1.z;++i)
{
if (p[i]!= m1.p[i])
{
return true;
}
}
return false;
}
Matrix& operator +=(const Matrix& m1)
{
for(int i=0;i<z;++i)
{
p[i]=p[i]+m1.p[i];
}return *this;
}
Matrix operator +(const Matrix& m1) const
{
Matrix m3 (r,c,0);
for(int i=0;i<z;++i)
{
m3.p[i]=p[i]+m1.p[i];
}
return m3;
}
Matrix& operator -=(const Matrix& m1)
{
for(int i=0;i<z;++i)
{
p[i]=p[i]-m1.p[i];
}return *this;
}
Matrix operator -(const Matrix& m1) const
{
Matrix m3 (r,c,0);
for(int i=0;i<z;++i)
{
m3.p[i]=p[i]-m1.p[i];
}
return m3;
}
Matrix operator *(const Matrix& m1) const
{
Matrix m3 (r,m1.c,0);
double s=0; //temp
if(c==m1.r)
{
for(int i=0;i<r;++i)
{
for(int j=0;j<m1.c;++j)
{
for(int k=0;k<m1.r;++k)
{
s+=this-> operator()(i,k)*m1(k,j);
}
m3.p[i*(m1.c)+j]=s;
s=0;
}
}return m3;
}
else
{
std::cout<<"Matrices are not compatible";
}
}
Matrix& operator *=(const Matrix& m1)
{
/*Matrix m3 (r,m1.c,0);
double s=0; //temp
for(int i=0;i<r;++i)
{
for(int j=0;j<m1.c;++j)
{
for(int k=0;k<m1.r;++k)
{
s+=this-> operator()(i,k)*m1(k,j);
}
m3.p[i*(m1.c)+j]=s;
s=0;
}
}
*this=m3;*/
*this = *this *m1;
return *this;
}
std::size_t rows() const
{
return r;
}
std::size_t cols() const
{
return c;
}
friend std::ostream& operator <<(std::ostream& x, const Matrix& m1)
{
for( int i=0;i<m1.r;++i)
{
for(int j=0;j<m1.c;++j)
{
x<<m1.p[i*m1.c+j]<<"\t";
}
std::cout<<std::endl;
}return x;
}
friend std::istream& operator >>(std::istream& y, Matrix& m1)
{
{
for( int i=0;i<m1.r;++i)
{
for(int j=0;j<m1.c;++j)
{
y>>m1.p[i*m1.c+j];
}
}
return y;
}
}
};
#endif // MATRIX_H
Please do let me know as to where I am wrong or missing something! I am trying to run MatrixProduct.cpp for different test cases.
Thanks in Advance.
So, as much as it is fast and convenient to put code into a header, it almost always leads to compile errors that take longer to track down than the time it takes to create the standard .h and .cpp files, especially with this much code.
I'm not exactly sure where the problem was, but it may have been the Matrix::operator>>(). You'll be able to find errors like this by using an IDE like eclipse and pressing Ctrl-i to auto-indent the code. Also, please check that I didn't mess up any of your logic formatting it.
Also, there's some academic trick question about memory allocation for matrices. if I remember correctly, you are supposed to allocate all the memory at once and then use pointers to refer to the array elements. I could be wrong and I'm not going to go into it now. Something like:
int rows(10000);
int cols(10000);
double* _data = (double*) malloc(rows * cols * sizeof(double));
double** data = (double**) malloc(rows * sizeof(double*));
for(int i = 0; i < rows; i++) {
data[i] = _data + (cols * i);
}
Please note that I have no idea if the matrix math is correct
matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <istream>
#include <ostream>
class Matrix {
public:
Matrix(std::size_t rows, std::size_t cols, double initValue);
Matrix(const Matrix& m1);
~Matrix();
Matrix& operator=(const Matrix& m1);
double& operator()(std::size_t i, std::size_t j);
const double& operator()(std::size_t i, std::size_t j) const;
bool operator==(const Matrix& m1) const;
bool operator!=(const Matrix& m1) const;
Matrix& operator+=(const Matrix& m1);
Matrix operator+(const Matrix& m1) const;
Matrix& operator-=(const Matrix& m1);
Matrix operator-(const Matrix& m1) const;
Matrix operator*(const Matrix& m1) const;
Matrix& operator*=(const Matrix& m1);
std::size_t rows() const;
std::size_t cols() const;
friend std::ostream& operator<<(std::ostream& x, const Matrix& m1);
friend std::istream& operator>>(std::istream& y, Matrix& m1);
private:
int r, c, z;
double *p;
};
#endif
matrix.cpp
#include "matrix.h"
#include <iostream>
#include <istream>
#include <ostream>
Matrix::Matrix(std::size_t rows, std::size_t cols, double initValue) :
r(rows),
c(cols),
z(r * c) {
p = new double [z];
for(int i = 0; i < z; ++i) {
p[i] = initValue;
}
}
Matrix::Matrix(const Matrix& m1) :
r(m1.r),
c(m1.c),
z(r*c) {
p = new double [z];
for (int i=0; i<z; ++i) {
p[i]=m1.p[i];
}
}
Matrix::~Matrix() {
delete [] p;
}
Matrix& Matrix::operator=(const Matrix& m1) {
if (*this == m1) {
return *this;
} else {
r = m1.r;
c = m1.c;
z = r * c;
delete[] p;
p = nullptr;
p = new double[m1.z];
for(int i = 0; i < z; ++i) {
p[i] = m1.p[i];
}
return *this;
}
}
double& Matrix::operator()(std::size_t i, std::size_t j) {
return p[i*c+j];
}
const double& Matrix::operator()(std::size_t i, std::size_t j) const {
return p[i*c+j];
}
bool Matrix::operator==(const Matrix& m1) const {
if(r==m1.r && c==m1.c) {
for(int i=0;i<z;++i) {
if (p[i] != m1.p[i]) {
return false;
}
}
} else if(r != m1.r || c != m1.c) {
return false;
}
return true;
}
bool Matrix::operator!=(const Matrix& m1) const {
if( r != m1.r || c != m1.c) {
return true;
}
for(int i = 0; i < m1.z; ++i) {
if (p[i] != m1.p[i]) {
return true;
}
}
return false;
}
Matrix& Matrix::operator+=(const Matrix& m1) {
for(int i=0;i<z;++i) {
p[i] = p[i] + m1.p[i];
}
return *this;
}
Matrix Matrix::operator+(const Matrix& m1) const {
Matrix m3 (r,c,0);
for(int i=0;i<z;++i) {
m3.p[i] = p[i] + m1.p[i];
}
return m3;
}
Matrix& Matrix::operator-=(const Matrix& m1) {
for(int i=0;i<z;++i) {
p[i] = p[i] - m1.p[i];
}
return *this;
}
Matrix Matrix::operator-(const Matrix& m1) const {
Matrix m3 (r, c, 0);
for(int i=0;i<z;++i) {
m3.p[i] = p[i] - m1.p[i];
}
return m3;
}
Matrix Matrix::operator*(const Matrix& m1) const {
Matrix m3 (r, m1.c,0 );
double s = 0;
if(c == m1.r) {
for(int i = 0; i < r; ++i) {
for(int j = 0; j < m1.c; ++j) {
for(int k = 0; k < m1.r; ++k) {
s += this->operator()(i,k)*m1(k,j);
}
m3.p[i * (m1.c) + j] = s;
s = 0;
}
}
return m3;
} else {
std::cout << "Matrices are not compatible";
}
}
Matrix& Matrix::operator*=(const Matrix& m1) {
*this = *this *m1;
return *this;
}
std::size_t Matrix::rows() const {
return r;
}
std::size_t Matrix::cols() const {
return c;
}
std::ostream& operator<<(std::ostream& x, const Matrix& m1) {
for( int i=0;i<m1.r;++i) {
for(int j=0;j<m1.c;++j) {
x << m1.p[i*m1.c+j] << "\t";
}
std::cout << std::endl;
}
return x;
}
std::istream& operator>>(std::istream& y, Matrix& m1) {
for( int i=0;i<m1.r;++i) {
for(int j=0;j<m1.c;++j) {
y >> m1.p[i * m1.c + j];
}
}
return y;
}
I am trying to create my own vector class. I want to overload the basic features of STL vector. My code is compiling by after testing it, a message "segmentation fault(core dumped is)" is shown. Could you show me where I can improve my code. Thank you in advance!
#include<iostream>
#include<fstream>
using namespace std;
class Vector
{
public:
Vector();
Vector(const Vector& vect);
~Vector();
Vector& operator =(const Vector& vect);
void insert(double element);
bool operator ==(const Vector& vect);
Vector& operator +(const Vector& vect);
Vector& operator -(const Vector& vect);
Vector& operator *(const Vector& vect);
int size();
double operator[](int num);
friend istream& operator >>(istream& input, Vector& vect);
friend ostream& operator <<(ostream& output, Vector& vect);
private:
double* data;
int num;
int max;
};
Vector:: Vector()
{
double* data = NULL;
int num = 0;
int max = 0;
}
Vector::Vector(const Vector& vect)// not sure if its correct
{
data = new double[vect.max];
memcpy(data, vect.data, sizeof(double) * vect.num);
num = vect.num;
max = vect.max;
}
Vector::~Vector()
{
if(data)
{
delete[] data;
data = 0;
}
}
void Vector:: insert(double element)
{
if(num < max)
{
*(data + num) = element;
}
else
{
double *tmp = new double[num * 2];
delete[] data;
*(data + num) = element;
max *= 2;
}
num++;
}
Vector& Vector:: operator = (const Vector& vect)// highly unlikely to be correct
{
if(this != &vect)
{
if(data)
{
delete[] data;
data = 0;
}
max = vect.max;
data = new double[max];
for(int i = 0; i < num; i++)
{
this->data[i] = vect.data[i];
}
}
return *this;
}
bool Vector:: operator ==(const Vector& vect)
{
bool isEqual = true;
if(this->num != vect.num)
{
isEqual = false;
}
for(int i = 0; i < num; i++)
{
if(this->data[i] != vect.data[i] )
{
isEqual = false;
}
}
return isEqual;
}
Vector& Vector:: operator +(const Vector& vect)
{
Vector result;
for (int i = 0; i < num; ++i)
{
result.insert(*(data + i) + *(vect.data + i));
}
return result;
}
Vector& Vector:: operator -(const Vector& vect)
{
Vector result;
for (int i = 0; i < num; ++i)
{
result.insert(*(data + i) - *(vect.data + i));
}
return result;
}
Vector& Vector::operator*(const Vector &vect)
{
Vector result;
for (int i = 0; i < num; ++i)
{
result.insert(*(data + i) * *(vect.data + i));
}
return result;
}
int Vector:: size()
{
return num;
}
double Vector::operator[](int num)
{
return *(data + num);
}
ostream &operator <<(ostream &output, Vector &vect)
{
output << "[";
for (int i = 0; i < vect.size(); ++i)
{
output << vect[i];
if (i < vect.size() - 1)
output << ",";
}
output << "]\n";
return output;
}
istream &operator >>(istream &input, Vector &vect)
{
double element;
input >> element;
vect.insert(element);
return input;
}
int main()
{
Vector vec;
for (int i = 0; i < 10; ++i)
{
vec.insert(i);
}
return 0;
}
Look closely at your insert function. Specifically at how you are re-sizing the array.
I have to replicate a vector class using an int and overload a bunch of operators. How ever every time I try to use the +, -, or / operator I get a runtime error which says invalid allocation size: 4294967295 bytes. Any feed back on how I can improve my code is welcome as well.
my code:
myArray.h
#include<iostream>
using namespace std;
class myArray{
private:
int *A;
int lenght;
int maxSize;
public:
myArray(){lenght = 0; maxSize = 0; A = new int[maxSize];}
myArray(int s){maxSize = s; lenght = 0; A = new int[maxSize];}
myArray(const myArray &M);
~myArray(){delete[] A;}
const int getMaxSize(){return maxSize;}
const int getLenght(){return lenght;}
const myArray& operator +(const myArray& A);
const myArray& operator -(const myArray A);
const int operator *(const myArray& A);
const myArray& operator /(const myArray A);
const myArray& operator +(int A);
const myArray& operator -(int A);
const int operator *(int A);
const myArray operator /(int A);
const myArray operator ++();
const myArray operator ++(int);
const myArray operator --();
const myArray operator --(int);
myArray operator -();
int operator [](int ind) const;
myArray& operator =(const myArray& rho);
void push(int n);
int pop();
void insert(int n, int pos);
int remove(int pos);
void resize(int newSize);
};
myException.h
#include<iostream>
#include<exception>
#include<string>
using namespace std;
class myException: public exception
{
private:
int code;
string reason;
public:
myException(){code = 0; reason = "Unknown";}
myException(int c, string r){code = c; reason = r;}
friend ostream& operator <<(ostream& outputStream, const myException A);
};
ostream& operator <<(ostream& outputStream, const myException A)
{
outputStream << "Code: " << A.code << " Reason: " << A.reason << endl;
return outputStream;
}
myArray.cpp
#ifndef MYARRAY_H
#define MYARRAY_H
#include "myArray.h"
#include "myException.h"
//Copy contructor
myArray::myArray(const myArray &M)
{
maxSize = M.maxSize;
lenght = M.lenght;
A = new int[maxSize];
for(int i = 0; i < M.lenght; i++)
A[i] = M.A[i];
}
//Adds the elements of the array with each other and returns the result
const myArray& myArray::operator +(const myArray& secondArray)
{
try
{
if(lenght != secondArray.lenght)
throw myException(10, "Different sizes!");
myArray result(secondArray);
for(int i = 0; i < lenght;i++)
result.A[i] = A[i] + secondArray.A[i];
return result;
}
catch(myException& e)
{
cout << e;
}
}
//Subtracts the elements of the array with each other and returns the result
const myArray& myArray::operator -(const myArray secondArray)
{
try
{
if(lenght != secondArray.lenght)
throw myException(10, "Different sizes!");
myArray result(secondArray);
for(int i = 0; i < lenght;i++)
result.A[i] = this->A[i] - secondArray.A[i];
return result;
}
catch(myException& e)
{
cout << e;
}
}
//Gets the dot product of 2 vectors
const int myArray::operator *(const myArray& secondArray)
{
try
{
if(lenght != secondArray.lenght)
throw myException(10, "Different sizes!");
int result = 0;
for(int i = 0; i < lenght;i++)
result += this->A[i] * secondArray.A[i];
return result;
}
catch(myException& e)
{
cout << e;
}
}
//Divides the elements of the array with each other and returns the result
const myArray& myArray::operator /(const myArray secondArray)
{
try
{
if(lenght != secondArray.lenght)
throw myException(10, "Different sizes!");
myArray result(secondArray);
for(int i = 0; i < lenght;i++)
result.A[i] = this->A[i] / secondArray.A[i];
return result;
}
catch(myException& e)
{
cout << e;
}
}
//Adds the elements of the array with an int and returns the result
const myArray& myArray::operator +(int A)
{
myArray result(*this);
for(int i = 0; i < lenght;i++)
result = this->A[i] + A;
return result;
}
//Subtracts the elements of the array with an int and returns the result
const myArray& myArray::operator -(int A)
{
myArray result(*this);
for(int i = 0; i < lenght;i++)
result = this->A[i] - A;
return result;
}
//Gets the dot product of a vector multiplied by an int
const int myArray::operator *(int A)
{
int result = 0;
for(int i = 0; i < lenght;i++)
result += this->A[i] * A;
return result;
}
//Divides the elements of the array with an int and returns the result
const myArray myArray::operator /(int A)
{
myArray result(*this);
for(int i = 0; i < lenght;i++)
result = this->A[i] / A;
return result;
}
//increments every element in the array by 1(Pre-increment)
const myArray myArray::operator ++()
{
for(int i = 0; i < lenght; i++)
++A[i];
return *this;
}
//increments every element in the array by 1(Post-increment)
const myArray myArray::operator ++(int)
{
myArray temp(maxSize);
for(int i = 0; i < lenght; i++)
temp.A[i] = A[i]++;
return temp;
}
//decrements every element in the array by 1(Pre-decrement)
const myArray myArray::operator --()
{
for(int i = 0; i < lenght; i++)
--A[i];
return *this;
}
//decrements every element in the array by 1(Post-decrement)
const myArray myArray::operator --(int)
{
myArray temp(maxSize);
for(int i = 0; i < lenght; i++)
temp.A[i] = A[i]--;
return temp;
}
//Makes every element in the array negative
myArray myArray::operator -()
{
for(int i = 0; i < lenght; i++)
A[i] = -A[i];
return *this;
}
//returns the number in the array using []
int myArray::operator [](int ind) const
{
try
{
if(ind > lenght)
throw myException(60, "Array index out of bounds");
return A[ind];
}
catch(myException& e)
{
cout << e;
}
}
//Assignment operator
myArray& myArray::operator=(const myArray& B)
{
delete [] A;
A = new int[B.maxSize];
lenght = B.lenght;
maxSize = B.maxSize;
for(int i = 0; i < B.lenght; i++)
{
A[i] = B.A[i];
}
return (*this);
}
//pushes the value inserted to the next available spot in the array
void myArray::push(int n)
{
try
{
if(lenght == maxSize)
throw myException(30, "Not enough space");
if(lenght == 0)
{
A[0] = n;
lenght++;
}
else
{
for(int i = 0; i < lenght; i++)
{
if(i+1 == lenght)
{
A[i+1] = n;
lenght++;
break;
}
}
}
}
catch(myException& e)
{
cout << e;
}
}
//Removes the last element in the array and returns it
int myArray::pop()
{
try
{
if(lenght <= 0)
throw myException(60, "Array index out of bounds");
int temp = A[lenght - 1];
A[lenght - 1] = NULL;
lenght--;
return temp;
}
catch(myException& e)
{
cout << e;
}
}
inserts an element at the specified position
void myArray::insert(int n, int pos)
{
try
{
if(pos > lenght)
throw myException(60, "Array index out of bounds");
for(int i = 0; i <= lenght; i++)
{
if(i == pos)
{
A[i-1] = n;
}
}
}
catch(myException& e)
{
cout << e;
}
}
//removes an element at a specified position an returns the value.
int myArray::remove(int pos)
{
try
{
if(pos < 0 || (pos > lenght -1))
throw myException(50, "Invalid Position");
int temp = A[pos];
A[pos] = NULL;
for(int i = pos; i < lenght; i++)
{
A[i] = A[i+1];
}
return temp;
}
catch(myException& e)
{
cout << e;
}
}
//Re sizes the entire array
void myArray::resize(int newSize)
{
int *B;
B = new int[newSize];
maxSize = newSize;
for(int i = 0; i < lenght; i++)
B[i] = A[i];
delete[] A;
A = B;
}
#endif
This is just a dummy main to test everything on the myArray class
main.cpp
#include "myArray.h"
int main()
{
int num;
myArray vector1;
myArray vector2(5);
myArray vector3;
vector1.resize(5);
//cout << "Max Size: " << vector1.getMaxSize() << endl;
for(int i = 0; i < 4; i++)
{
cin >> num;
vector1.push(num);
}
for(int i = 0; i < 4; i++)
{
cin >> num;
vector2.push(num);
}
vector3 = vector1 + vector2;
for(int i = 0; i < 4; i++)
cout << vector3.pop() << endl;
}
You create dynamic array with zero size in default constructor.
But in push method you try to set value to it if it's length is zero.
In C++ standard it says:
The effect of dereferencing a pointer returned as a request for zero
size is undefined.
You can only delete it. Fix your push method
I am trying to define a simple class to work with 2d matrices, called Matrix2D01, and having trouble with the + operator.
I have the += operator which is working fine,
Matrix2D01& Matrix2D01::operator+=(Matrix2D01& mat2) {
int i,j;
for (i=0;i<M;i++)
for (j=0;j<N;j++) mat[i][j]+=mat2[i][j];
return *this;
}
The + operator is defined:
Matrix2D01 Matrix2D01::operator+(Matrix2D01& mat2) {
Matrix2D01 result(1,1);
result=*this;
result+=mat2;
return result;
}
When i try to use the + operator, for example by
mat3=mat1+mat2;
the compiler gives an error:
../MatrixGames.cpp:17:12: error: no match for ‘operator=’ in ‘mat3 = Matrix2D01::operator+(Matrix2D01&)((* & mat2))’
If anyone can tell me what I'm doing wrong it will be greatly appreciated.
Thanks.
I also have a = operator defined,
Matrix2D01& Matrix2D01::operator=(Matrix2D01& mat2) {
if (this==&mat2) return *this;
int i,j;
for (i=0;i<M;i++) {
delete [] mat[i];
}
delete [] mat;
M=mat2.Dimensions()[0];
N=mat2.Dimensions()[1];
mat = new double* [M];
for (i=0;i<M;i++) {
mat[i]=new double [N];
}
for (i=0;i<M;i++)
for (j=0;j<M;j++)
mat[i][j]=mat2[i][j];
return *this;
}
here is a complete test case:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
using namespace std;
class Matrix2D01 {
protected:
int D;
double **mat;
int M,N;
public:
Matrix2D01(int m,int n);
Matrix2D01(int m,int n,double d);
~Matrix2D01();
vector <int> Dimensions() {vector <int> d(D,M); d[1]=N; return d;}
double* operator[](int i) {return mat[i];}
Matrix2D01& operator=(Matrix2D01& mat2);
Matrix2D01& operator+=(Matrix2D01& mat2);
Matrix2D01 operator+(Matrix2D01& mat2);
};
Matrix2D01::Matrix2D01(int m, int n) {
int i,j;
D=2;
M=m;
N=n;
mat = new double* [M];
for (i=0;i<M;i++) {
mat[i]=new double [N];
}
for (i=0;i<M;i++)
for (j=0;j<M;j++)
mat[i][j]=0;
}
Matrix2D01::Matrix2D01(int m, int n,double d) {
int i,j;
D=2;
M=m;
N=n;
mat = new double* [M];
for (i=0;i<M;i++) {
mat[i]=new double [N];
}
for (i=0;i<M;i++)
for (j=0;j<M;j++)
mat[i][j]=d;
}
Matrix2D01::~Matrix2D01() {
int i;
for (i=0;i<M;i++) {
delete [] mat[i];
}
delete [] mat;
}
Matrix2D01& Matrix2D01::operator=(Matrix2D01& mat2) {
if (this==&mat2) return *this;
int i,j;
for (i=0;i<M;i++) {
delete [] mat[i];
}
delete [] mat;
M=mat2.Dimensions()[0];
N=mat2.Dimensions()[1];
mat = new double* [M];
for (i=0;i<M;i++) {
mat[i]=new double [N];
}
for (i=0;i<M;i++)
for (j=0;j<M;j++)
mat[i][j]=mat2[i][j];
return *this;
}
Matrix2D01& Matrix2D01::operator+=(Matrix2D01& mat2) {
int i,j,M2,N2;
M2=mat2.Dimensions()[0];
N2=mat2.Dimensions()[1];
if ((M!=M2)||(N!=N2)) {
cout<<"error: attempted to add non-matching matrices";
return *this;
}
for (i=0;i<M;i++)
for (j=0;j<N;j++) mat[i][j]+=mat2[i][j];
return *this;
}
Matrix2D01 Matrix2D01::operator+(Matrix2D01& mat2) {
Matrix2D01 result(1,1);
result=*this;
result+=mat2;
return result;
}
int main() {
Matrix2D01 mat1(2,2,1);
Matrix2D01 mat2(2,2,2);
Matrix2D01 mat3(2,2,4);
mat3+=mat1;
mat3=mat1+mat2;
return 1;
}
Herb Sutter advocates the following canonical way to overload operator + (please read GotW, it is really well written and interesting):
Don't include operator + as a member function, instead make it a free function.
Pass one object by value and the other by const reference. This makes it possible to use move operators when you add to a temporary.
Implement in terms of operator +=:
Matrix2D01 operator+(Matrix2D01 a, const Matrix2D01 &b)
{
a += b;
return a;
}
I've posted the code of the Matrix class I had written for an assignment on Discrete Mathematics last Sem
Notice how the assignment operator and the copy constructor are implemented All you need to do is write an assignment operator (I'd recommend that you write a copy constructor as well)
#pragma once
#include <vector>
#include <istream>
#include <ostream>
class Matrix
{
private:
unsigned int rows, cols;
std::vector<std::vector<int> > matrix;
public:
// Creates a Matrix with the given dimensions and sets the default value of all the elements to 0
Matrix(unsigned int rows, unsigned int cols);
// Destructor
~Matrix();
// Converts the relation set into it's adjacency Matrix representation
static Matrix CreateFromRelationSet( std::vector<std::pair<int, int> > relationSet);
// Copy Constructor
Matrix(const Matrix& cSource);
// Assignment Operator
Matrix& operator=(const Matrix& cSource);
// Resets all the elements of the matrix to 0
void Reset();
// Resizes the matrix to the given size
void Resize(unsigned int rows, unsigned int cols);
// Returns the number of rows
unsigned int getRows();
// Returns the number of columns
unsigned int getCols();
// Returns the smallest element from the matrix
int getSmallestElement();
// Returns the greatest element from the matrix
int getGreatestElement();
// Returns true if element is found and sets the row and column
// Returns false if not found
bool getPosition(int element, int* i, int* j);
// Deletes a row from the Matrix
void DeleteRow(unsigned int row);
// Deletes a column from the Matrix
void DeleteColumn(unsigned int col);
// Returns the element at (i,j)
int& operator()(unsigned int i, unsigned j);
// Returns the element at (i,j). Use the () operators instead
int getElementAt(unsigned int i, unsigned j);
friend std::ostream& operator << (std::ostream& out, Matrix& m);
friend std::istream& operator >> (std::istream& in, Matrix& m);
Matrix operator + (Matrix M);
Matrix operator - (Matrix M);
Matrix operator * (Matrix M);
};
// For use with cin & cout
std::ostream& operator << (std::ostream& out, Matrix& m);
std::istream& operator >> (std::istream& in, Matrix& m);
#include "Matrix.h"
Matrix::Matrix(unsigned int rows, unsigned int cols)
{
this->rows = rows;
this->cols = cols;
matrix.resize(rows);
for(std::vector<int>& i: matrix)
i.resize(cols);
Reset();
}
Matrix::~Matrix()
{
}
// local helper function
int findMaxFromSet(std::vector<std::pair<int, int> > set)
{
int maxVal = 0;
for(unsigned int i = 0; i < set.size(); i ++)
{
int p = set[i].first > set[i].second ? set[i].first : set[i].second;
maxVal = maxVal > p ? maxVal : p;
}
return maxVal;
}
Matrix Matrix::CreateFromRelationSet (std::vector<std::pair<int, int> > relationSet)
{
int max = findMaxFromSet(relationSet);
Matrix M(max,max);
M.Reset();
for(auto i = relationSet.begin(); i != relationSet.end(); ++ i)
M(i->first - 1, i->second - 1) = 1;
return M;
}
void Matrix::Reset()
{
for (auto& i: matrix)
for(auto& j: i)
j = 0;
}
void Matrix::Resize(unsigned int rows, unsigned int cols)
{
matrix.resize(rows);
for(auto& i:matrix)
i.resize(cols);
}
unsigned int Matrix::getRows()
{
return rows;
}
unsigned int Matrix::getCols()
{
return cols;
}
Matrix::Matrix(const Matrix& cSource)
{
rows = cSource.rows;
cols = cSource.cols;
matrix = cSource.matrix;
}
bool Matrix::getPosition(int element, int* i, int* j)
{
for(unsigned int ii = 0; ii < getRows(); ii ++)
for(unsigned int jj = 0; jj < getCols(); jj ++)
if(matrix[ii][jj] == element)
{
*i = ii;
*j = jj;
return true;
}
return false;
}
Matrix& Matrix::operator=(const Matrix& cSource)
{
// check for self-assignment
if (this == &cSource)
return *this;
if(this->getRows() < cSource.rows)
{
this->rows = cSource.rows;
this->matrix.resize(cSource.rows);
}
if(this->getCols() < cSource.cols)
{
this->cols = cSource.cols;
for(auto& i:this->matrix)
i.resize(cSource.cols);
}
for(unsigned int i = 0; i < rows; i++)
for(unsigned int j = 0; j < cols; j++)
this->matrix[i][j] = const_cast<Matrix&>(cSource)(i,j);
return *this;
}
std::ostream& operator << (std::ostream& out, Matrix& m)
{
for(auto& i: m.matrix)
{
for(auto& j: i)
out<<j<<'\t';
out<<std::endl;
}
return out;
}
std::istream& operator >> (std::istream& in, Matrix& m)
{
for(auto& i: m.matrix)
for(auto& j: i)
in>>j;
return in;
}
Matrix Matrix::operator + (Matrix op)
{
// Find the rows and cols of the new matrix
unsigned int r = this->getRows() > op.getRows()?this->getRows():op.getRows();
unsigned int c = this->getCols() > op.getCols()?this->getCols():op.getCols();
// Create Matrices
Matrix A = *this;
Matrix B = op;
Matrix R(r,c);
// Assign values
for(unsigned int i = 0; i < A.rows; i++)
for(unsigned int j = 0; j < A.cols; j++)
R(i,j) = A(i,j) + B(i,j);
return R;
}
Matrix Matrix::operator - (Matrix op)
{
// Find the rows and cols of the new matrix
unsigned int r = this->getRows() > op.getRows()?this->getRows():op.getRows();
unsigned int c = this->getCols() > op.getCols()?this->getCols():op.getCols();
// Create Matrices
Matrix A = *this;
Matrix B = op;
Matrix R(r,c);
// Assign values
for(unsigned int i = 0; i < A.rows; i++)
for(unsigned int j = 0; j < A.cols; j++)
R(i,j) = A(i,j) - B(i,j);
return R;
}
Matrix Matrix::operator* (Matrix op)
{
Matrix A = *this;
Matrix B = op;
if(A.getCols() != B.getRows())
throw std::exception("Matrices cannot be multiplied");
Matrix M(A.getRows(), B.getCols());
for(unsigned int i=0 ; i<A.getRows() ; i++)
for(unsigned int j=0 ; j<B.getCols() ; j++)
for(unsigned int k=0 ; k<B.getRows() ; k++)
M(i,j) = M(i,j) + A(i,k) * B(k,j);
return M;
}
int& Matrix::operator()(unsigned int i, unsigned j)
{
return matrix[i][j];
}
int Matrix::getElementAt(unsigned int i, unsigned j)
{
return (*this)(i,j);
}
int Matrix::getSmallestElement()
{
int result = matrix[0][0];
for(auto i:matrix)
for(auto j : i)
if(j < result)
result = j;
return result;
}
int Matrix::getGreatestElement()
{
int result = matrix[0][0];
for(auto i:matrix)
for(auto j : i)
if(j > result)
result = j;
return result;
}
void Matrix::DeleteRow(unsigned int row)
{
matrix.erase(matrix.begin() + row);
rows --;
}
void Matrix::DeleteColumn(unsigned int col)
{
for(auto& i: matrix)
i.erase(i.begin() + col);
cols --;
}
UPDATE:
result=*this;
In your code you are trying to allocate result the value of *this using the assignment operator, but no assignment operator is defined and the compiler doesn't find a match
Writing an assignment operator overload will solve this issue.
And if you have a copy constructor you can do something like:
Matrix2D01 Matrix2D01::operator+(Matrix2D01& mat2) {
Matrix2D01 result = *this;
result+=mat2;
return result;
}
Writing Assignment Operators: http://www.learncpp.com/cpp-tutorial/912-shallow-vs-deep-copying/
And if you're interested in the details - here you go: http://www.icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html
Your operands should be const references. Otherwise, you
can't use a temporary to initialize them. (In this case, the
return value of operator+ is a temporary, and thus, cannot be
bound to the non-const reference of operator=.)
If your operator+ is a member, it should be const as well.
After all, it doesn't modify the object it is called on. So:
Matrix2D01& Matrix2D01::operator=( Matrix2D01 const& mat2 );
Matrix2D01& Matrix2D01::operator+=( Matrix2D01 const& mat2 );
Matrix2D01 Matrix2D01::operator+( Matrix2D01 const& mat2 ) const;
Also, your assignment operator is broken. (Think of what will
happen, if one of the allocations fails after you've freed the
original data.) In general, if you have to test for self
assignment, the assignment operator is broken.
So I have the += operator overloaded in a way that attempts to take advantage of the + operator that I've already defined. Namely that Polynomial + Polynomial returns a new Polynomial. So my += function basically tries to call this + function with the LHS as *this and the RHS as *this + B (where B is a Polynomial object passed by const reference to the function). I am getting an error. Where am I going wrong with this?
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cmath>
using namespace std;
void line(int lines);
class Polynomial
{
private:
int degree;
double* coeffs;
public:
//constructors
Polynomial() {degree=0;coeffs=new double[1];}
Polynomial(int deg) {degree=deg;coeffs=new double[deg+1];}
Polynomial(const Polynomial& A);
//mutators
void GetCoeffs(istream& in);
void EditCoeff(int deg);
void ResetCoeffs();
int Coeff(int deg);
void Randomize(int max);
//accessors
void Show(ostream& out);
int Degree() {return degree;}
//operators
Polynomial operator+(const Polynomial& B); //Polynomial + Polynomial
friend Polynomial operator +(double c, Polynomial& A); //c + Polynomial
Polynomial operator +(double c); //Polynomial + c
void operator +=(const Polynomial& B); //Polynomial+=Polynomial
void operator =(Polynomial& A);
Polynomial operator*(int k);
Polynomial operator*(Polynomial& A);
};
int main()
{
Polynomial A(5);
A.Randomize(4);
A.Show(cout);
line(2);
Polynomial B=A+8;
B.Show(cout);
return 0;
}
Polynomial Polynomial::operator*(int k)
{
Polynomial C(degree);
C=*this;
for (int i=degree; i>=0; i--)
C.coeffs[i]*=k;
return C;
}
Polynomial operator +(double c, Polynomial& A)
{
Polynomial C=A;
C.coeffs[0]+=c;
return C;
}
Polynomial Polynomial::operator +(double c)
{
Polynomial C=*this;
C.coeffs[0]+=c;
return C;
}
void Polynomial::Randomize(int max)
{
for (int i=degree; i>=0; i--)
{
coeffs[i]=rand()%(max+1) + 1;
if ((rand()%(101) + 1)%2 == 0)
coeffs[i]*=-1;
}
}
void Polynomial::operator =(Polynomial& A)
{
if (degree==A.degree)
{
for (int i=degree; i>=0; i--)
{
coeffs[i]=A.coeffs[i];
}
}
}
Polynomial Polynomial::operator+(const Polynomial& B)
{
if (degree>=B.degree)
{
Polynomial C(degree);
C=*this;
for (int i=B.degree; i>=0; i--)
{
C.coeffs[i]=coeffs[i]+B.coeffs[i];
}
return C;
}
else
{
Polynomial C=B;
for (int i=degree; i>=0; i--)
{
C.coeffs[i]=coeffs[i]+B.coeffs[i];
}
return C;
}
}
void Polynomial::operator+=(const Polynomial& B)
{
*this = (*this + B);
}
int Polynomial::Coeff(int deg)
{
return coeffs[deg];
}
void line(int lines)
{
for (int i=0; i<lines; i++)
cout << endl;
}
void Polynomial::GetCoeffs(istream& in)
{
for (int i=degree; i>=0; i--)
{
in >> coeffs[i];
}
in.ignore();
}
void Polynomial::Show(ostream& out)
{
if (coeffs[degree]>0)
cout << " ";
for (int i=degree; i>=0; i--)
{
if (coeffs[i]>=0)
{
if (i!=degree)
out << " + ";
out << coeffs[i];
}
else
{
if (coeffs[i]<0)
out << " - ";
out << 0-coeffs[i];
}
if (i>1)
out << "x^" << i;
else if (i==1)
out << "x";
}
}
Polynomial::Polynomial(const Polynomial& A)
{
coeffs=new double[A.degree+1];
degree=A.degree;
for (int i=A.degree; i>=0; i--)
{
coeffs[i]=A.coeffs[i];
}
}
Polynomial Polynomial::operator*(Polynomial& A)
{
int deg=A.degree+degree;
Polynomial P(deg);
for (int i=deg; i>=0; i--)
P.coeffs[i]=0;
for (int i=deg; i>=0; i--)
{
for (int j=A.degree; j>=0; j--)
{
P.coeffs[i+j]+=coeffs[i]*A.coeffs[j];
}
}
return P;
}
Your problem is that *this + B is a temporary, and temporary objects can't be bound to non-const references.
Of course, there's no reason that the RHS of an assignment can't be const. Try:
void operator=(/* HERE */ const Polynomial& A);
Most of your other operators aren't using const where they should either. For example:
Polynomial operator+(const Polynomial& B) /* HERE */ const; //Polynomial + Polynomial
friend Polynomial operator +(double c, /* HERE */ const Polynomial& A); //c + Polynomial
Only assignment operators should be non-const members, and they should accept const right operands. Normal binary operators that create new objects should be const wrt both left and right operands.
Often it is done other way around. People make binary + operator (usually non-member) that takes advantage of += operator (a member) that is already defined.
Where am I going wrong with this?
You should use std::vector instead of a raw pointer.
You have violated the rule of three.
You didn't follow the convention creating a member operator+= and a free operator+.
Try this:
// UNTESTED
class Polynomial
{
private:
std::vector<double> coeffs;
public:
//constructors
Polynomial() : coeffs(1) {}
Polynomial(int deg) : coeffs(deg+1) {}
// Don't need copy constructor
// Don't need destructor
// Don't need assignment operator
...
int Degree() {return coeffs.size()-1;}
//operators
Polynomial& operator+=(const Polynomial& B) {
if(Degree() < B.Degree())
coeffs.resize(B.Degree()+1);
for(int i = 0; i <= B.Degree(); ++i)
coeffs[i] += B.coeffs[i];
return *this;
}
};
Polynomial operator+(Polynomial A, const Polynomial& B) {
return A += B;
}