- ベストアンサー
C++ポインタ代入の影響は?
- C++でオート変数にポインタを代入した場合、スコープから外れると開放されるため、再利用時に不定値になる可能性がある。
- Funcが呼び出されるたびに最初に設定したintDataTestのデータを読み込みたいが、方法がわからない。
- TestClassのデータm_intDataをセットしている間、intDataTestに同じポインタが代入されるため、Func内での操作が影響する。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
> Funcを抜けた時にintDataTestがスコープから外れるために、intDataTest = m_intDataも開放されてしまうのでしょうか? intDataTest(int *型)がスコープから外れた時に解放されるのは intDataTest変数のみです。 m_intDataは、TestClassインスタンスがdeleteされない限り、 解放されることはありません。 提示されたコードの省略部分に問題があるのだろうと思います。 可能性1:TestClass内のどこか別の処理でm_intDataをNULLにする処理が あり、そこが通っている。 可能性2:Func処理のどこかにpClass->SetData(NULL)しているところがある。 可能性3:1回目のFunc呼び出しと2回目のFunc呼び出しで異なるTestClass インスタンスを使っている。 このコードは、回答1さんに指摘された通り、TestClassインスタンスの 生成を記述していませんから、元のコードもそのあたりのインスタンス の扱いに見落としがありそうに思います。 例えば、もし -------------------------------------------- TestClass* pClass = new TestClass; pClass->SetData( intData ); Func( pClass ); for( int i = 0; i < 5; i++ ) { TestClass* pClass = new TestClass; Func( pClass ); // この後、複雑ないろいろな処理 } -------------------------------------------- となっていたら、2回目のFuncはintDataTestがNULLになります。 こんなケースでも同様です。 -------------------------------------------- TestClass testClass; testClass.SetData( intData ); Func( &testClass ); for( int i = 0; i < 5; i++ ) { TestClass testClass; Func( &testClass ); // この後、複雑ないろいろな処理 } --------------------------------------------
その他の回答 (4)
- redfox63
- ベストアンサー率71% (1325/1856)
> タイミングさえ間違えなければ、intDataを開放してもm_intDataを > 開放しても処理的には等価だと考えていました まぁタイミングさえ間違えなければ開放されますが運用していく上で誤解されやすいように思います クラス自体をブラックボックスのライブラリ化した際など 自分で確保したメモリーだから自身で解放するだろうとプログラマーは思うのではありませんか? なのにTestClass側で勝手に開放されてしまっていたら思わぬバグに悩まされるといったことがありそうです
お礼
再度のご回答、どうもありがとうございました。 メンテナンス性を考慮すると、おっしゃる通り、newとdeleteは同じところの方が良いですね。参考になりました。
- Tacosan
- ベストアンサー率23% (3656/15482)
ポインタ変数がスコープを抜けても, そのポインタ変数に与えられた値が自動的に解放されることはありえません. というか, もしそうなら (double-free はありえるけど) メモリリークは起きないでしょ? intDataTest の値が 0 になるということは, このコードだと「この後, 複雑ないろいろな処理」のところで SetData を実行しないといけないはずなので, その辺を確認しないとダメでしょうね.
お礼
ご回答、どうもありがとうございました。おっしゃる通り、領域の開放し忘れの方がよく聞く問題ですね。アドバイスいただいた通り、他のところも確認します。ありがとうございました。
- redfox63
- ベストアンサー率71% (1325/1856)
TestClassのデストラクタで delete m_intData;をするのはおかしいでしょう deleteで削除するのは newで作成した物に対してです 単にポインタに代入しただけなら deleteで削除するのではなく NULLの代入だけでいいでしょう main側で処理終了後に delete[] intData; といった具合に削除するようにしましょう
お礼
早速のご回答ありがとうございました。元の複雑なコードを単純化したつもりが、自分の理解不足で質問したかったところと別の場所でもご指摘を受けてしまい、どうもすみません。元のコードでは、ご指摘の通り、TestClassのデストラクタではNULLを代入していただけかもしれません。 ですが、mainで領域を確保したintDataのポインタを、TestClassのSetDataでm_intDataに代入しているので、タイミングさえ間違えなければ、intDataを開放してもm_intDataを開放しても処理的には等価だと考えていました。(No.1さんにご指摘を受けた、TestClassが正しく作られていると仮定してですが。) この考え方も間違っているでしょうか。 お手数おかけして申し訳ありませんが、よろしくお願いします。
- buriburi3
- ベストアンサー率44% (353/792)
このコードではpClassのインスタンスが作られていません。 スコープを外れる云々以前に pClass->SetData( intData ); の時点でpClassが無効なアドレスです。 TestClass* pClass = new TestClass ; になっていればintDataTestの実体は開放されません。
お礼
早速のご回答ありがとうございました。元の複雑なコードを単純化したつもりが、自分の理解不足で質問したかったところと別の場所でもご指摘を受けてしまい、どうもすみません。元のコードではご指摘の通り、 TestClass* pClass = new TestClass; などとなっているはずです。 元のコードがご指摘の通りになっているとすると、intDataTestの実体は開放されないので、Funcを何度呼び出しても他でm_intDataを書き換えなければ、同じ値が入っているということなのでしょうか。 Funcを抜けた時の私の理解は間違っているとして、本物コードでの、2度目のFunc呼び出しでは、intDataTestがすべて0になっているのは、(質問には出てない)別の箇所と考えられますか? お手数おかけして申し訳ありませんが、よろしくお願いします。
お礼
ご丁寧な解説をどうもありがとうございました。 今、本物コードを確認できる環境にありませんが、アドバイスいただいたところを確認します。