1

リストを使用した後に要素を削除しようとしている二重リンク リスト (この場合は素数を格納するため) を作成しました。リストのデストラクタに単純なループを記述しました。ただし、各要素が削除された後、各要素に保持されている値を出力できます。メモリが解放された後、「不正なアクセス」エラーが発生することが予想されます。さらに、Activity Monitor を使用して、プログラム実行のさまざまな時点で使用中のリソースを表示しました。リンクされたリストが作成されたとき (明らかに) メモリ使用量が大幅に増加しましたが、デストラクタが呼び出された後もわずかに増加しました。私は何かが間違っていると収集します。

リストの各メンバーに対して「delete」ステートメントが呼び出されていますが、何もしていないようです。以下のデストラクタからの関連コードを含めました。リストと要素は、'new' ステートメントを使用して作成されます。「current」、「head」、および「tail」タグは、リスト要素 (ノード) へのポインターです。

PrimeList::~PrimeList()
{
    // delete list elements
    do
    {
        current = tail;
        tail = tail->previous;
        delete current;
    }
    while( tail != NULL );

    // nullify the pointers
    head = NULL;
    tail = NULL;
    current = NULL;

    // reset size
    size = 0;
}

洞察はありますか?

4

5 に答える 5

2

オブジェクトを削除しても、オブジェクトが占有していたメモリが変更されるとは限りません。まして、そのメモリがその後のアクセスで使用できなくなることはありません。プログラムが削除されたメモリにアクセスしないようにするさまざまな方法があります。たとえば、削除されたメモリを異常なビット パターンで上書きするデバッグ アロケータを使用したり、valgrindなどの動的分析ツールを使用したりします。

于 2012-08-26T23:55:11.307 に答える
1

要素を削除した後に要素にアクセスするのはバグです。もちろん、バグのあるコードは期待どおりには機能しません。そのため、このようなコードは避けようとしています。

デストラクタは問題ないようです。最も可能性が高いのは、デストラクタが内部的にメモリを再利用できるようにしているということです。その内容を変更したり、新しいオブジェクトを割り当てたりしていないため、同じ内容が「たまたま」残っています。

于 2012-08-26T23:50:14.963 に答える
1

リストの先頭を参照で delete メソッドに渡しましたか?

それ以外の場合は、リストのコピーを削除しようとしているだけなので、アクセスしようとしてもリストは残っています。

コード全体を見ることはできませんが、デストラクタについては、次のようにする必要があります。

PrimeList::~PrimeList()
{
  deleteList( &head); // pass the reference to the head pointer
}

void PrimeList::deleteList( struct node** headRef)
{
  struct node* head = *headRef;
  // now apply your deletion algorithm
}
于 2012-08-26T23:55:03.180 に答える
1

deleteオブジェクトが使用するメモリを別のオブジェクトが再利用できるようにするだけです (そして、デストラクタがあればそれを呼び出します) 。メモリを消去したり、使用不可などのマークを付けたりすることはありません(少なくとも、保証されているわけではありません-気分が良ければ可能性があります)。将来、そのメモリは別のオブジェクトに割り当てられる可能性があり、その時点で上書きされます。

deleted メモリはシステムに返されません。プロセスによって保持され、将来newの s (およびmalloc...) で再利用されます。これが、Activity Monitor がまだそのメモリを使用していると判断する理由です。リストの割り当てが正しく解除されたかどうかを判断するより良い方法があります。「c++ メモリ リーク検出器」などを検索してください。

于 2012-08-26T23:55:35.100 に答える
1

「あなたを助けている」のはおそらくあなたのコンパイラです。リンクリストにデストラクタを実装する良い方法は、再帰です。リスト内の各エントリにクラス Node があると仮定すると、

class Node {
    public:
    ~Node() {delete this->next;}
};

PrimeList::~PrimeList() {
    delete head;
}
于 2012-08-26T23:56:43.903 に答える