0

私はコンピューター サイエンスの学生で、動的なデータ構造であるリンク リストを作成する仕事をしています。私は現在、単一リンクリストに取り組んでおり、すべてのノードデータを追加、削除、およびダンプする機能を正常に構築しました。

ただし、私の「高度なプログラミング」の講師が、混乱やその他の問題を避けるために、リストからノードを削除するとき、またはオブジェクトのメモリを解放するときは、デコンストラクター内で実行する必要があると述べたことを思い出してください。だから私は動いた:

delete[] _del;

これはうまく機能し、ノードのデコンストラクターに移動しました:

#include "Node.h"

// Node.cpp

Node::Node(const int &inData, const int &inId)
{
    _id = inId;
    _data = inData;
    nextNode = NULL;
}

// Deconstructor to delete the node when using List.Del()
Node::~Node()
{
    delete[] this;
}

私のリストでは、ノードのデコンストラクターは次のようなポインターを介して呼び出されます。

_del->~Node();

これにより、アサーションエラーが発生します。ノードのデコンストラクターで「これ」を使用していると思いますか?

御時間ありがとうございます。

4

4 に答える 4

2

まず、アロケータを作成していて、作成時に新しい配置を使用する場合を除いて、オブジェクトデストラクタを直接呼び出さないでください。第二に、も使用deleteしない限り、すべきではありません。そして最後に、それは悪い習慣ですが、基準によれば合法です。全部ではなく、ただ電話してみませんか?delete[]new[]delete thisdelete theNode

編集:いくつかのコメント/追加の質問に対処します。

ヒープに単一のインスタンスを割り当てるには、を使用しますtheNode = new Node。返されたポインタは、で解放する必要がありますdelete theNode。newを呼び出すと、メモリが割り当てられてNode::Node()から、コンストラクタが呼び出され、内部状態を設定できるようになります。deleteを呼び出すNode::~Node()と、割り当てられたメモリが呼び出されて解放されます。デストラクタは、ノードが使用するすべてのものをクリーンアップする責任がありますが、ノード自体が使用するメモリはクリーンアップしません。

ノードの配列を割り当てるには、を使用しますtheNodes = new Node[10];。これらは。で削除しdelete[] theNodesます。new/deleteとnew[]/delete[]の混合は未定義の動作です。

newの配置は、すでに割り当てられているメモリにオブジェクトを作成するメソッドです。この場合、デストラクタを直接呼び出す唯一の理由があります。オブジェクトに割り当てられたメモリを解放せずに、オブジェクトを分解する(つまり、オブジェクト自体をクリーンアップする)必要があります。

の呼び出し後に「this」または削除されたインスタンスのメンバーを参照しない限り、関数などの呼び出しdelete thisは合法です。これは、たとえば参照カウントオブジェクトでは有効な手法ですが、本当に必要な場合を除いて、避けるべきものと見なされることがよくあります。Suicide()delete this

あなたのための正しい解決策はかなり明白です、あなたが今電話するところ、代わり~Nodeに単に電話してください。delete theNode

于 2011-02-19T09:31:52.760 に答える
1

デコンストラクタ内からオブジェクトを削除するにはどうすればよいですか?

そうではありません。デストラクタは、オブジェクト自体ではなく、オブジェクトが所有するリソースをクリーンアップします。

delete の使用を削除する必要があり、Node に割り当てられたもの (リスト クラス?) は、その割り当てを解除する責任を負うべきです。これを行う最も簡単な方法は、ノードをリストに割り当ててリストに追加するポイントを 1 つだけリスト クラスに配置し、ノードを削除して割り当てを解除するポイントを 1 つだけ持つことです (前述の Del メソッド)。リストが空になるまで、リスト クラスのデストラクタで Del を繰り返し呼び出します。

于 2011-02-19T09:30:51.633 に答える
1
Node::~Node()
{
    delete[] this;
}

未定義の動作。ほとんどの場合、プログラムがクラッシュします。

ちなみに、 と には違いがdelete thisありdelete[] thisます。いつかは大丈夫delete thisかもしれませんが、を使用して割り当てることはできないため、そうではありません。配列へのポインタではありません。これは 1 つのオブジェクトへのポインターです。delete[] thisthisnew[]

于 2011-02-19T09:26:56.590 に答える
0

以前の回答が示唆しているように、デコンストラクターは未定義の動作です。次の理由によります。

いつ

delete[] _del;

実行されます。デコンストラクタで削除しようとしているのと同じオブジェクトを削除しようとします

delete[] this;

コーステキストの意味は、削除されるオブジェクトに関連付けられているメモリをクリアしたい場合は、このオブジェクトのデコンストラクタでも解放する必要があるということです。たとえば、idやデータがポインタだった場合:

Node::~Node()
{
   delete _id;
   delete _data;
}
于 2011-02-19T09:33:18.613 に答える