1. ホーム
  2. c++

[解決済み] 削除されたポインタに対してVisual Studioは何をするのですか?

2022-07-11 15:26:21

質問

私が読んでいる C++ の本には、ポインタを削除するときに delete 演算子を使用してポインターを削除すると、そのポインターが指している場所のメモリは解放され、上書きできるようになるそうです。 また、ポインタは再割り当てされるか、または 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....


明らかに、delete が呼び出されると、ポインタの指すアドレスが変わります!

なぜこのようなことが起こるのでしょうか? これは特に Visual Studio と関係があるのでしょうか?

また、delete が指すアドレスを変更できるのであれば、なぜ delete は自動的にポインタを NULL に設定しないのでしょうか?

どのように解決するのですか?

に格納されているアドレスが ptr に格納されているアドレスが、常に 00008123 ...

これはおかしいと思ったので、少し調べてみると、次のようなことがわかりました。 マイクロソフトのブログ投稿 には、quot;C++ オブジェクトを削除する際の自動ポインタ サニタイズについて説明したセクションがあります。

...NULLに対するチェックは一般的なコード構成であり、サニタイズ値としてNULLを使用することと組み合わせた既存のNULLに対するチェックは、根本原因に本当に対処する必要がある本物のメモリ安全問題を偶然にも隠してしまう可能性があることを意味します。

オペレーティング システムの観点から、これはゼロ アドレス (NULL) と同じメモリ ページにありますが、0x8123 でのアクセス違反は、より詳細な注意を必要とするため、開発者にとってより目立つものになります。

削除された後のポインタに対して Visual Studio が何を行うかを説明しているだけでなく、なぜポインタを NULL に設定しなかった理由も説明しています。


この機能は、quot;SDL checks"設定の一部として有効になっています。 有効/無効を切り替えるには、次のサイトにアクセスしてください。 PROJECT -> Properties -> Configuration Properties -> C/C++ -> General -> SDL checks

これを確認するために

この設定を変更し、同じコードを再実行すると、次のような出力が得られます。

ptr = 007CBC10
ptr = 007CBC10


feature" が引用符で囲まれているのは、同じ場所への 2 つのポインタがある場合、delete を呼び出すことでサニタイズされるのは ONE のみをサニタイズするからです。 もう 1 つのポインターは無効な場所を指したままです。


アップデートを行います。

C++ プログラミングの経験を 5 年以上積んだ後、この問題全体が基本的に無意味なものであることに気づきました。もしあなたが C++ プログラマーで、まだ newdelete を使用してスマートポインタ(この問題全体を回避できる)を使用する代わりに生のポインタを管理するには、Cプログラマへのキャリアパスの変更を検討する必要があるかもしれません;)