0

次のような二重にリンクされたリストがあるとします

class list
{
    /*...*/

private:
    struct node
    {
       node* prev;
       node* next;
       int* value;
    }

    node* first; //NULL if none
    node* last; //NULL if none

    /*...*/
}

最初のノードを削除し、その値へのポインタを返す関数を書きたい場合、この実装はメモリ リークを起こしますか?

int* returnFrontValue()
{
   if(list_is_Empty())
        throw -1;
   else
   {
        node* v = first;
        int* returnMe = v->value;

        first = first->next;
        if(!first)
            last = NULL;

        delete v;
        first->prev = NULL;

        return returnMe;
   }
}

returnMe動的に割り当てられた int を指しているために、この実装がメモリ リークを起こすかどうか興味があります。代わりに and を最後にint returnMe = *(v->value);返す方がよいでしょうか?&returnMe;

私のdelete v->value;前に明示的にする必要がありdelete v;ますか?さまざまなポインターがある場合、メモリの削除がどのように機能するかについて混乱しています。

4

1 に答える 1

2

がどのように割り当てられたかはわかりませんintが、動的に割り当てられた (削除したノードとは別の割り当てとして) というあなたの言葉を信じます。

その場合、いいえ、あなたはまだ何も漏らしていませんが、あなたは運命を誘惑しています. intへのポインターがまだ存在するため、リークではありません。したがって、削除することもできます。しかし今、責任は発信者にあります。を呼び出すとreturnFrontCaller、値へのポインターが得られます。これは、使い終わったときに呼び出す必要がありdeleteます。

それはあまり直感的ではありません。通常、 new/delete呼び出しは同じ場所で一致する必要があります。を呼び出すとnew、 も呼び出しますdelete。電話が他の場所で発生した場合、new電話deleteが私の責任であるとは思いません。

Why do you store anしかし、なぜint* instead of anint`で値が動的に割り当てられるのでしょうか? 関数が int のコピーではなくポインタを返すのはなぜですか?

その変更を行った場合、メモリ管理は必要ありません。呼び出し元は int を取得し、「誰が呼び出すか」を気にする必要はありませんdelete

または、スマート ポインター クラスを使用してラップし、メモリ管理を処理することもできます。

于 2012-12-09T10:44:03.887 に答える