0

So my problem is this...when I am trying to allocate memory to a pointer, it fails.

This is my MatrixClass definition..

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;
};

I am trying to do this..

MatrixClass BB;
BB = A + B;

So here is my overloaded + function..

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 +

Once temp returns...it calls the copy constructor...passing temp as 'rhs' and 'this' would refer to 'BB'? (Am I right in thinking this?)

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

Also the error that i get is this... 'Unhandled exception at 0x75a0b727 in assignment.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x002af924..'

So basically the qestion I am asking is..why the hell is is the line where I am trying to allocate memory to 'dataptr' in the copy constructor giving me problems..it only does this when calling the copy constructor from the return value 'temp'..

Thanks!

4

2 回答 2

3

Short answer: you have not implemented Rule of Three properly. In C++11, Rule of Five.

Long answer: you have not implemented operator=. The compiler generated one is not enough for your case.

Apart from that my guess is that your default constructor doesn't allocate memory for dataptr. If so, then you're using dataptr in operator+ without even allocating memory for it. That is the reason why your program crashes. Even if the default constructor allocates memory, the problem is still there as the value of rhs.M and rhs.N may be different from what you assume in the default constructor (which is, as you said, 4 and 5 respectively).

So allocate memory for dataptr in operator+. Also, before allocation, you've to deallocate the memory which it may point to, and you also need to set M and N to the values of rhs.M and rhs.N respectively.

于 2012-04-21T15:49:43.900 回答
1

不,詹姆斯,你错了,当operator+返回时,复制构造函数将被调用以将局部变量temp转换为赋值运算符范围内的临时匿名对象。在复制构造函数中,this会引用这个临时变量,而不是BB。

因为LHS已经存在,返回时不会再“构造” operator+,而是“赋值”,所以需要重载operator=。(有关更多详细信息,请参见此处operator=。)默认设置只是按位复制,因此如果您没有重载 operator=,则dataptr当匿名临时对象被销毁时,它将在匿名临时对象的析构函数中被释放(我们希望)超出范围(在复制后立即),BB 将指向已释放的内存。您还将泄漏已在 BB 中分配的任何内存,因为 BB 在分配之前不会被销毁。BBdataptr会泄漏,而临时对象dataptr会被释放两次。

因此,尽管最终分配和复制内存 3 次有点糟糕,但为了使 + 和 = 在所有情况下都有效,您需要执行以下操作:

  • operator+更改为MatrixClass temp;正确分配和解除分配MatrixClass temp(rhs.M, rhs.N);temp.dataptr
  • 正如您所做的那样,在复制构造函数中分配新内存dataptr并将其复制过来。
  • 重载operator=,以便它首先检查自分配(this == &rhs),如果不是自分配,则释放现有的dataptr,然后分配一个新的并复制rhs.
于 2012-04-21T17:24:29.670 回答