[迷信] free に NULL を渡すとクラッシュする
まずは次のコードをご覧ください。
{
free(ptr);
}
上のコードを見て何の違和感も感じないようであれば、あなたは迷信にとらわれている可能性があります。論より証拠ですので、JIS X3010:2003の「7.20.3.2 free関数」から引用することにします。
機能 free関数は,ptrが指す領域を解放し,その後の割付けに使用できるようにする。ptrが空ポインタの場合,何もしない。
free の引数に空ポインタ(すなわち NULL)を渡した場合は何もしないことが明記されています。このことからも分かるように、free の引数が NULL であるかどうかの判別は無意味に冗長なだけです。
ただし、ライブラリのバグなどによって、NULL を渡すと本当に誤動作する環境も存在することでしょう。その場合には、NULL かどうかの判別を行っている箇所にはしかるべきコメントを書くべきです。あるいは、free 関数の内部で NULL かどうかの判別をさせると、排他制御が行われるなどの理由でオーバーヘッドが大きいので、外部で判別しているということもあるでしょう。その場合も理由のコメントが不可欠かと思います。
ちなみに、C++の delete 式はどうかというと、JIS X3014:2003の「5.3.5 delete式」によると...
いずれの形式であっても,deleteの演算対象がの値が空ポインタの場合,その演算の効果はない。
とあるため、free 関数と同じく NULL を渡しても問題ありません。なお、operator delete を再定義して、内部で空ポインタの判定を行っていない場合でも問題ありません。なぜなら、delete 式はメモリの解放に先立ってデストラクタを呼出さなければならないため、operator delete を呼出す前に空ポインタの判定を行っているからです。ただし、delete 式ではなく、operator delete を直接呼出す場合はこの限りではありません。
トラックバック
ブックナビゲーション
- 技術情報
- Boost C++ Libraries メモ
- C++と組込み環境
- C++サンプル集
- C++テンプレート集
- C++プログラマのためのC言語入門
- C/C++迷信集
- [迷信] 'A'~'Z' の値は連続している
- [迷信] 0xe-0xe はゼロ
- [迷信] 1 バイトは 8 ビット
- [迷信] 2の累乗による割り算と右シフトは等価
- [迷信] FILE 型は構造体
- [迷信] abs は常に非負の値を返す
- [迷信] argv[0] はプログラム名
- [迷信] char 型は符号付き
- [迷信] double の出力書式は "%lf"
- [迷信] fflush で入力バッファをクリア
- [迷信] free でメモリを開放する
- [迷信] free に NULL を渡すとクラッシュする
- [迷信] gets は単純に fgets に置き換えられる
- [迷信] isalpha 関数の引数は char 型
- [迷信] new に失敗すると NULL が返る。
- [迷信] scanf ではバッファオーバーランを防げない
- [迷信] scanf でキーボードから入力
- [迷信] setjmp マクロの返却値は変数に代入できる
- [迷信] sizeof は定数式
- [迷信] void main(void)
- [迷信] とりあえず memset で初期化
- [迷信] アルゴリズム関数内で関数オブジェクトはコピーされない
- [迷信] オブジェクトの動的生成に失敗するとメモリリークする
- [迷信] コンストラクタから例外を送出してはならない
- [迷信] コンストラクタで自身をゼロクリア
- [迷信] コンパイラはプログラマの心を察してくれる
- [迷信] コンパイルエラーが出るのでアクセス指定子を修正
- [迷信] ソースコード中の即値を全廃せよ
- [迷信] ソースファイルの末尾に }
- [迷信] データ列のソートには qsort 関数を使うべし
- [迷信] プログラムは必ず main から始まる
- [迷信] 一重引用符の中には一文字しか書けない
- [迷信] 今どき int が 16 ビットの処理系なんて無い
- [迷信] 入力データ格納用配列のサイズは BUFSIZ
- [迷信] 割付けたメモリはプログラマが自分で解放しなければならない
- [迷信] 実数型とは浮動小数点型のことである
- [迷信] 引用符で囲んだヘッダ名はカレントディレクトリから探索する
- [迷信] 文字列から整数への変換には atoi
- [迷信] 構造体のタグ名は下線で始める
- [迷信] 構造体はクラスではない
- [迷信] 識別子に使える文字は英数字と下線のみ
- [迷信] 非局所オブジェクトは外部結合
- C99関数・マクロ・前処理スクリプト集
- C言語再入門
- C言語徹底入門
- Drupal メモ
- TOPPERS 情報
- ライブラリ開発入門
- 分割コンパイルをきわめる
- 擬似プロセッサを作る
- 車輪の再発明
- 過去の情報


> なお、operator delete
> なお、operator delete を再定義して、内部で空ポインタの判定を行って
> いない場合でも問題ありません。
これ、そうとは言い切れないようです。
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#348
現行の規格ではヌルポインタに対する delete で対応する operator delete が
呼び出されるかどうかは不明確で、最新のドラフトではこれが「不定」であると
明記されることになっています。
コメントありがとうございます。
なるほど、ご指摘ありがとうございます。
これはちょっと読み取るのが困難ですね。