0

だから私の問題はこれです...私がポインタにメモリを割り当てようとしているとき、それは失敗します。

これは私の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 ++例外:メモリ位置0x002af924のstd :: bad_alloc ..'

だから基本的に私が尋ねている質問は..なぜ地獄は私が問題を与えているコピーコンストラクターの'dataptr'にメモリを割り当てようとしている行です..それは戻り値からコピーコンストラクターを呼び出すときにのみこれを行います'temp' ..

ありがとう!

4

2 に答える 2

3

簡単な答え:あなたは三つのルールを適切に実装していません。C ++ 11では、5つのルール

長い答え:あなたは実装していませんoperator=。コンパイラが生成したものは、あなたの場合には十分ではありません。

それとは別に、私の推測では、デフォルトのコンストラクターはにメモリを割り当てませんdataptr。もしそうなら、あなたはそれにメモリを割り当てることさえせずにで使用dataptrしています。operator+それがあなたのプログラムがクラッシュする理由です。デフォルトのコンストラクターがメモリを割り当てたとしても、問題はの値として存在し、デフォルトのコンストラクターで想定しているものrhs.Mrhs.Nは異なる場合があります(つまり、それぞれ、4と言っ5たとおりです)。

したがって、でメモリを割り当てdataptrます operator+。また、割り当てる前に、それが指す可能性のあるメモリの割り当てを解除する必要があります。また、との値をそれぞれに設定する必要MNありrhs.Mますrhs.N

于 2012-04-21T15:49:43.900 に答える
1

いいえ、James、あなたは間違っています。returnsの場合、代入演算子のスコープ内の一時的な匿名オブジェクトにoperator+ローカル変数を変換するためにコピーコンストラクターが呼び出されます。tempコピーコンストラクターでthisは、BBではなくこの一時変数を参照します。

LHSはすでに存在しているため、operator+戻ったときに再度「構築」されることはなく、「割り当て」られるため、オーバーロードする必要がありますoperator=。(詳細については、ここを参照してください。)デフォルトoperator=ではビット単位のコピーが作成されるため、operator =をオーバーロードしなかった場合dataptr、匿名の一時オブジェクトが破棄されるときに、デストラクタで解放されます(願っています)。スコープ外(コピーされた直後)で、BBは解放されたメモリを指しています。また、BBは割り当てられる前に破棄されないため、BBにすでに割り当てられているメモリもリークします。BBdataptrはリークし、一時オブジェクトdataptrは2回解放されます。

したがって、メモリの割り当てとコピーを3回行うのはちょっと残念ですが、すべての状況で+と=を機能させるには、次のことを行う必要があります。

  • operator+変更MatrixClass temp;するとMatrixClass temp(rhs.M, rhs.N);temp.dataptr適切に割り当てられ、割り当てが解除されます。
  • あなたがしているように、コピーコンストラクタで新しいメモリを割り当ててdataptrコピーします。
  • オーバーロードoperator=して、最初に自己割り当てをチェックし、自己割り当て(this == &rhs)でない場合は、既存のものを解放してからdataptr、新しいものを割り当てて、をコピーしrhsます。
于 2012-04-21T17:24:29.670 に答える