以下のようなマクロ定義を見かけることがあります。
1 |
#define SAFE_DELETE(p) if (p) {delete p;} |
昔々、マイクロソフトがDirectXのサンプルで上記のようなマクロを定義していたことがあり、恐らく、多くの人がそのサンプルのままで覚えた結果、特に深く考えずに実装しているケースも少なくないのでしょう。
ポインタがnullじゃないことを判定した後、deleteするという処理です。
delete対象のポインタがnullだった場合、どうなるのでしょう?
未定義の動作でしょうか?
アクセス例外でハングアップしたり、ニュージャージー州に住む叔母に勝手にメールを送るような動作を引き起こしたりするでしょうか?
答えは「何も起こらない」
deleteにnullポインタを渡しても安全であると規格にも明記されています。
In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject representing a base class of such an object.
__n3337 5.3.5 Delete
知っている人には当たり前でも、案外知らずにC++を使っている人も多いように感じます。
nullかどうかを気にせずポインタをdelete出来るかわりに、今度は別の、気をつけなければいけないことが生じます。
そう、自分でdelete演算子を定義する場合です。
1 2 3 4 5 6 7 8 |
// global deleteをユーザー定義のdeleteに置き換える void operator delete( void* p ) { if (p) { user_defined_free(p); // ユーザー定義のメモリ解放処理 } } |
規格に準ずる為にはnullを許容する実装になっていなければいけません。
まとめ
- nullポインタをdeleteに渡しても問題無い
- オリジナルのdelete演算子を定義する場合はnullポインタに対応しなければいけない