1. ホーム
  2. c++

[解決済み] ポインタを削除した後、NULLにするのは良い習慣ですか?

2022-04-24 12:24:46

質問

まず最初に言っておきます。 スマートポインターを使えば、このような心配は無用です。

次のコードの問題点は何ですか?

Foo * p = new Foo;
// (use p)
delete p;
p = NULL;

に端を発したものです。 回答・コメント という質問がありました。からの1件のコメント ニール・バタワース アップヴォート

<ブロッククオート

C++では、削除後にポインタをNULLに設定することは、普遍的なグッドプラクティスではありません。それが良いことである場合もあれば、無意味であり、エラーを隠してしまう場合もあるのです。

それが役に立たない状況もたくさんあります。しかし、私の経験では、損をすることはない。誰か教えてください。

どのように解決するのですか?

ポインタを0(標準C++では"null"、CのNULL定義は多少異なる)に設定すると、二重削除によるクラッシュを回避できます。

次のように考えてみましょう。

Foo* foo = 0; // Sets the pointer to 0 (C++ NULL)
delete foo; // Won't do anything

ところがだ。

Foo* foo = new Foo();
delete foo; // Deletes the object
delete foo; // Undefined behavior 

つまり、削除されたポインタを0にしないと、二重削除をした場合にトラブルが発生するのです。削除後のポインタを0にすることに反対する論拠は、そうすることで二重削除のバグを覆い隠し、処理されないままにしておくということでしょう。

もちろん、二重削除のバグがないのが一番ですが、所有権のセマンティクスやオブジェクトのライフサイクルによっては、実際に実現するのは難しいかもしれません。私は、UBよりもマスクされたダブルデリートバグを好みます。

最後に、オブジェクトの割り当て管理に関する補足ですが、以下のサイトを参考にしてください。 std::unique_ptr は、厳密な所有権/特異な所有権に対応します。 std::shared_ptr を使用するか、あるいは他のスマートポインタの実装を使用するか、ニーズに応じて選択します。