5

「ProgrammingInterviewsExposed」という本から次のコードを見ています。

bool deleteStack( Element **stack ){
      Element *next;
      while( *stack ){
            next = (*stack)->next;
            free( *stack );
            *stack = next;
      }
      return true;
}

私はC++やCにあまり詳しくないので、これはばかげた質問かもしれませんが、ポインターを解放した後に何かをポインターに割り当てると問題が発生しませんか?

4

4 に答える 4

8

あなたの例で*stackは、はポインタです。ポインタが指すメモリを解放してから、ポインタを新しい変数に割り当てるのは完全に安全です。

安全でない唯一のことは、*stackそれを解放した後に逆参照することです。

free( *stack );
next = (*stack)->next;

が指すメモリには、呼び出し*stack後に予測できないコンテンツが含まれているため(プロセスにアクセスできなくなる可能性もあるため)、正しくありません。free

于 2013-01-21T16:47:26.630 に答える
4

いいえ、それは大丈夫だ。これを行うことで、実際には「ポインタを解放」することはありません。

 free( *stack );

ただし、ポインタが指す動的に割り当てられたメモリを解放します*stack。あなたがするとき:

*stack = next;

別のメモリブロックを指すポインタを作成します。それだけです。

于 2013-01-21T16:49:11.250 に答える
1

それをするのは安全です。あなたがそのようなものを見るとき、あなた(*stack)はそれを「スタックによって指し示される」のように考えることができます。freeはメモリ位置へのポインタを期待しているため、スタックが指す「メモリスロット」をプロセス仮想メモリから解放しています。これは、メモリアドレス(つまり、ポインタ)のスペースがまだ使用可能であり、再利用できることを意味します。
また、これはおそらく便利だと思い->ます。矢印表記を使用する場合、C / C++では一般的な使用のために簡略化された2つの異なる表記を使用しています。だから、これは:これstack->nextと同じです:(*stack).next 頑張ってください。

于 2013-01-21T16:56:56.813 に答える
1

解放後にポインタ変数に割り当てるNULLのは、解放されたアドレスに対して間接参照が発生したかどうかを識別するためのヒントをコードに保持することだけです。

解放されたポインターにNULLを割り当てない場合、その解放されたポインター変数を参照解除すると、動作は未定義になります(クラッシュの可能性が50%、ヒープの破損の可能性が残ります)。しかし、それが設定されている場合、それはNULL確かにクラッシュします。ヒープが破損した場合、1つの場所でクラッシュするよりも、バグを特定するのが困難になります。

解放されたポインタがコード内で決して削除されないように考えないでください。プロジェクトが長期間維持されると、コードを誤って追加(または変更)する可能性があります。

于 2013-01-21T18:24:03.403 に答える