所以我的问题是这个...当我试图为指针分配内存时,它会失败。
这是我的MatrixClass定义..
class MatrixClass
{
public:
MatrixClass(int m, int n);
MatrixClass(void);
virtual ~MatrixClass(void);
double getRead(int num1, int num2) const;
double& getReadWrite(int num3, int num4);
void set(int i,int j,double value);//set value at i,j to value
MatrixClass(const MatrixClass &rhs);
void assign(int M,int N);
MatrixClass sum1(const MatrixClass& rhs) const;
MatrixClass operator+(const MatrixClass& rhs);//overloading the + operator
MatrixClass operator-();
private:
double* dataptr;
int M;
int N;
};
我想这样做..
MatrixClass BB;
BB = A + B;
所以这是我的重载+功能..
MatrixClass MatrixClass::operator +(const MatrixClass &rhs)
{
MatrixClass temp;
//temp.M = this->M + rhs.M;
//temp.N = this->N + rhs.N;
for(int i = 0;i < M;i++)
{
for(int j = 0; j<N;j++)
{
temp.dataptr[i * N + j] = this->getReadWrite(i,j) + rhs.dataptr[i*N+j];
}
}
return temp;
}//end operator +
一旦temp返回......它调用复制构造函数...将temp传递为'rhs'而'this'将引用'BB'? (我是否正确地想到这一点?)
MatrixClass::MatrixClass(const MatrixClass &rhs)//copy constructor
{
this->M = rhs.M;
this->N = rhs.N;
dataptr = 0;
if(rhs.dataptr != 0)
{
dataptr = new double[M * N];//allocate memory for the new object being assigned to...
// the line here where I try to allocate memory gives me an error.....Am I right in
//thinking that this would be assigning memory to dataptr of 'BB'?? Values are assigned to //'M' and 'N' fine....
int num = sizeof(double);
memcpy(this->dataptr,rhs.dataptr,M*N*sizeof(double));
}
else
{
this->dataptr = 0;
}
}//end copy constructor
我得到的错误是这个...'在assignment.exe中的0x75a0b727处未处理的异常:Microsoft C ++异常:std :: bad_alloc在内存位置0x002af924 ..'
所以基本上我要问的问题是..为什么到底是我试图在复制构造函数中为'dataptr'分配内存给我带来问题的行...这只是在调用复制构造函数时才这样做返回值'temp'..
谢谢!
答案 0 :(得分:3)
简短回答:您尚未正确实施Rule of Three。 In C++11, Rule of Five
答案很长:你没有实施operator=
。编译器生成的一个对你的情况来说还不够。
除此之外,我的猜测是你的默认构造函数没有为dataptr
分配内存。如果是这样,那么您在dataptr
中使用operator+
,甚至没有为其分配内存。这就是你的程序崩溃的原因。即使默认构造函数分配内存,问题仍然存在,因为rhs.M
和rhs.N
的值可能与您在默认构造函数中假设的值不同(正如您所说,{{1分别是}和4
。
因此,在5
中为dataptr
分配内存。此外,在分配之前,您必须释放它可能指向的内存,并且还需要将operator+
和M
设置为N
和rhs.M
的值分别
答案 1 :(得分:1)
不,詹姆斯,你错了,当operator+
返回拷贝构造函数时,将调用将局部变量temp
转换为赋值运算符范围内的临时匿名对象。在复制构造函数中,this
将引用此临时变量,而不是BB。
由于LHS已经存在,当operator+
返回时它不会再“构建”,它将被“分配”,因此您需要重载operator=
。 (有关更多详细信息,请参阅here。)默认operator=
只是进行按位复制,因此如果不重载operator =,dataptr
将被释放(我们希望)匿名临时对象的析构函数,当它超出范围(在复制后立即被销毁)时被销毁,而BB将指向释放的内存。你也会泄漏已经在BB中分配的任何内存,因为BB在被分配之前不会被销毁。 BB的dataptr
会泄漏,而临时对象的dataptr
将被释放两次。
所以,虽然你最终分配和复制内存三次很糟糕,为了让+和=在所有情况下工作,你需要做以下事情:
operator+
中将MatrixClass temp;
更改为MatrixClass temp(rhs.M, rhs.N);
,以便temp.dataptr
得到正确分配和解除分配。dataptr
分配新内存并将其复制。operator=
以便它首先检查自我分配(this == &rhs)
,如果它不是自我分配,则释放现有的dataptr
,然后分配一个新的rhs
并复制{ {1}}。