Posted at

NULLでないポインタは実体がなくても呼び出し可能

More than 3 years have passed since last update.

変数がポインタならNULLチェックしてから使うのが当たり前である。

しかしNULLチェックだけでは不完全である。

以下のような宣言の関数があるとする。


test

void Test::func() // 静的でないメンバ

{
if (this) { // NULLでないとき
printf("hello world\n");
}
}

以下のようにすると、インスタンスが無くても呼び出せる。


run

    Test *pT = new Test();

delete pT; // 削除
pT->func(); // 呼び出す
/*hello world*/ //正常終了(たぶん)

ここで言いたいのはインスタンスを削除してもポインタをNULLに戻さない限り、メンバにアクセスできてしまうことだ。

静的でなくてもインスタンスが無くても呼べてしまう特性は非常にバグりやすい。

しかも、VisualStudioは気付いてくれないことが多く、メモリを書き換えるような関数にアクセスしてメモリ破壊などが起きてやっと止まる。

デバッガでこれを見るとまるで実体があるかのように見えたりして悩むことになる。

メモリ解放とこのバグが離れた位置にあると追跡が難しくなるので要注意だ。


まとめ

C++にはインスタンスの有無を調べる機能がないようなので気を付けるしかない。

NULLチェックだけでなく、NULLに戻す方を徹底しないとバグがなくならない。