ねむみ高まる

文章力がないので、文章を書く練習をしています。

【C++】delete後のダングリングポインタにアクセスしてみた

メモリ解放後、無効なアドレスを指しているポインタのことを「ダングリングポインタ」と一般的には呼ぶらしいです。

ダングリングポインタにアクセスするとどうなるの??という感じだったので調べてみました。 環境はMicrosoft Visual Studio Community 2015、Debug実行、x86(32bit)です。

まず、下記のソースコードのように、new int → deleteしてからアクセスしてみます。

#include <iostream>

using namespace std;

int main()
{
    int *a = new int(4);

    delete a;

    cout << *a << endl;

    return 0;
}

delete a;のところでブレークポイントを貼って実行してみると、次の画像のようになりました。 アドレス0x00DD6188に4byteで確保されています。前後は no man's land(0xfdfdfdfd)ですね。

f:id:nemumitakamaru:20190115223553p:plain

F5を押して実行してみると、次の画像のような感じでクラッシュしました。

f:id:nemumitakamaru:20190115223734p:plain

aが0x8123??0x00DD6188から変わってる??と思ってGoogleで検索を掛けてみると、下記のページを見つけました。

stackoverflow.com

Security Development Lifecycle (SDL) checksというものが有効になっていると、delete後、勝手に無効な値(0x8123)が入るようです。 これ有効にしておけば、ダングリングポインタにアクセスすることがなくなるので良いですね。

今回はダングリングポインタにアクセスしたいのでSDL checksを外します。 外し方は上記のサイトより引用↓

PROJECT -> Properties -> Configuration Properties -> C/C++ -> General -> SDL checks

SDL checksを外してから実行すると、無事?クラッシュすることもなく、ダングリングポインタにアクセスし、標準出力に値を出すことに成功しました。 deleteすると元の箇所は0xddで埋められるので、0xddddddddとなり、-572662307という数値になっています。

f:id:nemumitakamaru:20190115230422p:plain

また、cout << *a << endl;したあと、不思議なことに0x00DD6188周辺のメモリの値が色々と書き換えられていました。。何故そのようなことになっているかは、また今後調べてみます。