web-dev-qa-db-ja.com

NULLポインタを削除しても安全ですか?

NULLポインタを削除しても安全ですか?

そしてそれは良いコーディングスタイルですか?

270
qiuxiafei

deleteはとにかくチェックを実行するので、あなたの側でそれをチェックすることはオーバーヘッドを追加し、より見栄えがよくなります。 deleteの後で非常に良い方法でポインタをNULLに設定することです(二重削除やその他の同様のメモリ破損の問題を避けるのに役立ちます)。

デフォルトでdeleteが次のようにパラメータをNULLに設定していた場合も大好きです

#define my_delete(x) {delete x; x = NULL;}

(私はRとLの値について知っていますが、それはいいのではないでしょうか?)

236
ruslik

C++ 0xドラフト標準から。

$ 5.3.5/2 - "[...]どちらの方法でも、deleteのオペランドの値はNULLポインタ値になることがあります。[... '"

もちろん、NULL値を持つポインタを「削除」する人はいませんが、実行しても安全です。理想的にはNULLポインタの削除をするコードを持つべきではありません。しかし、ポインタの削除(例えばコンテナ内)がループの中で行われるときには時々役に立ちます。 NULLポインタ値の削除は安全なので、削除するNULLオペランドを明示的にチェックしなくても削除ロジックを実際に書くことができます。

余談ですが、C Standardの$ 7.20.3.2では、NULLポインタを 'free'にしても何もしないと言われています。

Free関数は、ptrによって指されたスペースの割り当てを解除します。つまり、追加の割り当てに使用できるようになります。 ptrがNULLポインタの場合、何もしません。

73
Chubsdad

はい、安全です。

NULLポインタを削除しても問題ありません。割り当てられていないポインターがゼロに初期化されてから単純に削除された場合、関数の末尾でのテスト数が減少することがよくあります。


前の文が混乱を招いたので、例外的に安全ではありませんが、記述されているものの例:

void somefunc(void)
{
    SomeType *pst = 0;
    AnotherType *pat = 0;

    …
    pst = new SomeType;
    …
    if (…)
    {
        pat = new AnotherType[10];
        …
    }
    if (…)
    {
        …code using pat sometimes…
    }

    delete[] pat;
    delete pst;
}

サンプルコードで選ぶことができるあらゆる種類のnitがありますが、その概念は(私が望む)明確です。ポインタ変数はゼロに初期化されるので、関数の最後にあるdelete操作は、それらがソースコード内でnullでないかどうかをテストする必要はありません。とにかくライブラリコードがそのチェックを実行します。

43

NULLポインタを削除しても効果はありません。必ずしも必要ではないからといって必ずしも良いコーディングスタイルではありませんが、悪くもありません。

良いコーディング方法を探しているのであれば、代わりにスマートポインタを使用することを検討してください。そのため、deleteはまったく必要ありません。

20
Brian R. Bondy

Ruslikの答えを補完するために、C++ 14ではその構文を使うことができます。

delete std::exchange(heapObject, nullptr);
5
ashrasmun

削除演算子をオーバーロードしない限り、安全です。あなたが削除演算子をオーバーロードし、null条件を処理しない場合、それはまったく安全ではありません。

3
user4016479

[] NULL(つまり、配列構文)を削除するのはできない安全(VS2010)であることを私は経験しました。これがC++標準に準拠しているかどうかはわかりません。

それはis NULLを削除しても安全です(スカラー構文)。

0
pheest