ページ 11

C++のポインタに関して質問!

Posted: 2017年9月17日(日) 18:34
by nanashino
例えば、次のようなコードがあるとします。

class A
{
public:

A() { *m_pNum = 5; }
~A() {}
int* Get() { return m_pNum; }

private:

int* m_pNum;
};

class B
{
public:

B() {}
~B() {}

void Func()
{
int* Num;
A* a = new A();
Num = a->Get();
delete a;
cout << *Num << endl;
}
};

int main()
{
B b;
b.Func();
return 0;
}

BのFuncという関数は、Aが持っているm_pNumという変数(ポインタ)を受け取り、aをdeleteしてから受け取った変数を参照しています。
コンパイル自体は通るのですが、実行すると恐らくcoutのところでエラーが出るかと思います。
deleteしたクラスが持っていたポインタを参照しようとしているので当然のことなのですが、
deleteした後、Num変数は何を持っているのかを知りたいです。

長々しく下手な説明になってしまいましたが、どなたかお教えください。m(__)m

Re: C++のポインタに関して質問!

Posted: 2017年9月17日(日) 19:22
by みけCAT
ソースコードを提示する際は、BBCodeが有効な(無効にしない)状態で、
BBCodeのcodeタグの開始タグと終了タグの組(開始タグが先)で囲んでいただけると、
見やすくてありがたいです。
nanashino さんが書きました:実行すると恐らくcoutのところでエラーが出るかと思います。
初期化していないm_pNumをデリファレンスしているので、A() { *m_pNum = 5; }のところでアクセス違反になる可能性があります。
ここを実行してアクセス違反にならなければ、m_pNumに偶然値を書き込める領域へのポインタが入っていたということなので、
読めるのに書けないというのは通常使われても、書けるのに読めないというのは通常使われないと思われるので、同じ領域を読んでいるcoutでもエラーは出ないと予想できます。
もしくは最適化でポインタのアクセスが消える場合は…どうなるかわかりません。
(実際に実験を行った所、デバッガ上で実行するとアクセス違反になるのに、直接実行するとアクセス違反にならずに5が表示されました。
危険なので実験以外でこのようなコードを書いてはいけません。)
nanashino さんが書きました:deleteしたクラスが持っていたポインタを参照しようとしているので当然のことなのですが、
クラスをdeleteしても、m_pNumをデリファレンスする前にちゃんと有効な領域へのポインタを代入しており、かつその領域を開放していなければ、安全なはずです。
nanashino さんが書きました:deleteした後、Num変数は何を持っているのかを知りたいです。
deleteしても(デストラクタで変なことをしなければ)クラスの外には影響がないはずなので、もし実行されればdeleteする前と変わらずm_pNumに入っているゴミが入ったままである可能性が高いでしょう。

Re: C++のポインタに関して質問!

Posted: 2017年9月17日(日) 19:50
by みけCAT
main関数を

コード:

int main()
{
    B b;
    int* hoge = new int;
    b.Func();
    delete hoge;
    return 0;
}
と書き換えたところ、アクセス違反が発生しました。
デタラメな場所にデータを書き込んだため、何らかの管理用データを破壊していることが予想できます。