[c++] Visual Studioは削除されたポインタで何をするのですか?なぜですか?


Answers

/sdlコンパイルオプションの副作用があります。 VS2015プロジェクトではデフォルトでオンになっているため、/ gsで提供されているものを超える追加のセキュリティチェックが可能です。 プロジェクト/プロパティ/ C / C ++ /一般/ SDLチェック設定を使用して変更します。

MSDNの記事から引用:

  • 限られたポインタのサニタイズを実行します。 逆参照を伴わない式や、ユーザー定義のデストラクタを持たない型では、削除の呼び出しの後にポインタ参照が無効なアドレスに設定されます。 これは、古いポインタ参照の再利用を防ぐのに役立ちます。

MSVCを使用する場合、NULLに削除されたポインタを設定することは悪い習慣であることに注意してください。 これは、デバッグヒープとthis / sdlオプションの両方から得られるヘルプを無効にするので、無効なフリー/削除呼び出しをプログラムで検出できなくなります。

Question

私が読んでいるC ++の本では、 delete演算子を使ってポインタを削除すると、そのポインタが指している位置のメモリが "解放"され、上書きされることが示されています。 また、ポインタが再割り当てされるかNULL設定されるまで、ポインタは同じ場所を指し続けることも記載されていNULL

しかし、Visual Studio 2012では、 これは事実ではないようです!

例:

#include <iostream>

using namespace std;

int main()
{
    int* ptr = new int;
    cout << "ptr = " << ptr << endl;
    delete ptr;
    cout << "ptr = " << ptr << endl;

    system("pause");

    return 0;
}

このプログラムをコンパイルして実行すると、次のような出力が得られます。

ptr = 0050BC10
ptr = 00008123
Press any key to continue....

削除が呼び出されると、ポインタが指し示すアドレスが明らかに変わる!

なぜこうなった? これは特にVisual Studioと関係がありますか?

とにかく指しているアドレスを変更することができます削除、なぜ自動的にいくつかのランダムなアドレスの代わりにNULLにポインタを設定しないでしょうか?




ポインタを削除した後も、それが指し示すメモリは有効である可能性があります。 このエラーを明示するために、ポインタ値は明白な値に設定されています。 これは本当にデバッグプロセスに役立ちます。 値がNULLに設定されている場合、プログラムフローに潜在的なバグとして表示されることはありません。 だから、 NULLに対して後でテストするときにバグを隠すかもしれません。

もう1つのポイントは、実行時オプティマイザがその値をチェックしてその結果を変更することがある点です。

以前の時代にMSは値を0xcfffffff設定し0xcfffffff




delete ptr;
cout << "ptr = " << ptr << endl;

一般的にさえ(上記のように、注意:これは逆参照とは異なります)無効なポインタの値(ポインタをdeleteと無効になります)は実装定義の動作です。 これはCWG#1438で導入されました。 こちらもhere

その前に、無効なポインタの値を読み取る前に、未定義の動作があったことに注意してください。以上のことは未定義の動作になります。




Links