2

私はかなり大きなコードを書いている初期段階にあります。私はそのように1つのクラスを定義しました:

class GPUMD {
    private:
        double xhi, xlo, yhi, ylo, zhi, zlo;
        int numAtoms;
        Atom *atoms;
    public:
        GPUMD();
        ~GPUMD();
};

デストラクタは次のように定義されます。

GPUMD::~GPUMD() {
    if(atoms != NULL)
        delete [] atoms;
}

現在、コードはこれを行います:

int main(int argc, char *argv[]) {
    GPUMD gpumd;
    exit(0);
}

glibc で検出されたエラーが表示されます: 無効なポインターを解放しようとしています。valgrind を使用すると、このエラーは GPUMD のデストラクタに起因することがわかります。なんらかの理由で、そのポインターに何も割り当てていないにもかかわらず、atoms != NULL テストが true を返しています。何故ですか?

編集: コンストラクターは次のように定義されます。

GPUMD::GPUMD() {}
4

2 に答える 2

6

atomsコンストラクターで明示的に初期化されていないNULLか、有効なポインターではないためです。コンストラクターを次のように変更します。

GPUMD::GPUMD() : numAtoms(0), atoms(NULL) {}

ポインタの 、または はノーオペレーションであるためatoms != NULL、 の前のチェックは不要であることに注意してください。以下は安全です。delete[]delete[]deleteNULL

GPUMD::~GPUMD() {
    delete [] atoms;
}

動的に割り当てられたメンバーがGPUMDあるため、インスタンスのコピーを防止するGPUMDか、代入演算子とコピー コンストラクターを実装する必要があります ( What is The Rule of Three? を参照)。

C++ として、動的メモリを管理する代わりにvector<Atom>(またはスマート ポインターの) を使用することを検討してください。vector

于 2012-10-25T19:31:09.247 に答える
1

ポインターに何も割り当てない場合 (つまり、初期化しない場合)、その値は未定義です。そうではありません (まったくの偶然NULLかもしれませんが、その可能性はほとんどありません。)変数だけが自動的にゼロ初期化されます。NULLstatic

簡単に言うとNULL、コンストラクターで次のように初期化します。

GPUMD::GPUMD()
: atoms(NULL)
{ }

または、POD 型のイニシャライザが気に入らない場合 (理由はありません)、次のようにします。

GPUMD::GPUMD()
{ atoms = NULL; }
于 2012-10-25T19:31:53.580 に答える