• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C++ オート変数にポインタを代入したら?)

C++ポインタ代入の影響は?

このQ&Aのポイント
  • C++でオート変数にポインタを代入した場合、スコープから外れると開放されるため、再利用時に不定値になる可能性がある。
  • Funcが呼び出されるたびに最初に設定したintDataTestのデータを読み込みたいが、方法がわからない。
  • TestClassのデータm_intDataをセットしている間、intDataTestに同じポインタが代入されるため、Func内での操作が影響する。

質問者が選んだベストアンサー

  • ベストアンサー
  • Lchan0211
  • ベストアンサー率64% (239/371)
回答No.4

> 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 );     // この後、複雑ないろいろな処理   } --------------------------------------------

aneja
質問者

お礼

ご丁寧な解説をどうもありがとうございました。 今、本物コードを確認できる環境にありませんが、アドバイスいただいたところを確認します。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (4)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.5

> タイミングさえ間違えなければ、intDataを開放してもm_intDataを > 開放しても処理的には等価だと考えていました まぁタイミングさえ間違えなければ開放されますが運用していく上で誤解されやすいように思います クラス自体をブラックボックスのライブラリ化した際など 自分で確保したメモリーだから自身で解放するだろうとプログラマーは思うのではありませんか? なのにTestClass側で勝手に開放されてしまっていたら思わぬバグに悩まされるといったことがありそうです

aneja
質問者

お礼

再度のご回答、どうもありがとうございました。 メンテナンス性を考慮すると、おっしゃる通り、newとdeleteは同じところの方が良いですね。参考になりました。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

ポインタ変数がスコープを抜けても, そのポインタ変数に与えられた値が自動的に解放されることはありえません. というか, もしそうなら (double-free はありえるけど) メモリリークは起きないでしょ? intDataTest の値が 0 になるということは, このコードだと「この後, 複雑ないろいろな処理」のところで SetData を実行しないといけないはずなので, その辺を確認しないとダメでしょうね.

aneja
質問者

お礼

ご回答、どうもありがとうございました。おっしゃる通り、領域の開放し忘れの方がよく聞く問題ですね。アドバイスいただいた通り、他のところも確認します。ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

TestClassのデストラクタで delete m_intData;をするのはおかしいでしょう deleteで削除するのは newで作成した物に対してです 単にポインタに代入しただけなら deleteで削除するのではなく NULLの代入だけでいいでしょう main側で処理終了後に delete[] intData; といった具合に削除するようにしましょう

aneja
質問者

お礼

早速のご回答ありがとうございました。元の複雑なコードを単純化したつもりが、自分の理解不足で質問したかったところと別の場所でもご指摘を受けてしまい、どうもすみません。元のコードでは、ご指摘の通り、TestClassのデストラクタではNULLを代入していただけかもしれません。 ですが、mainで領域を確保したintDataのポインタを、TestClassのSetDataでm_intDataに代入しているので、タイミングさえ間違えなければ、intDataを開放してもm_intDataを開放しても処理的には等価だと考えていました。(No.1さんにご指摘を受けた、TestClassが正しく作られていると仮定してですが。) この考え方も間違っているでしょうか。 お手数おかけして申し訳ありませんが、よろしくお願いします。

全文を見る
すると、全ての回答が全文表示されます。
  • buriburi3
  • ベストアンサー率44% (353/792)
回答No.1

このコードではpClassのインスタンスが作られていません。 スコープを外れる云々以前に pClass->SetData( intData ); の時点でpClassが無効なアドレスです。 TestClass* pClass = new TestClass ; になっていればintDataTestの実体は開放されません。

aneja
質問者

お礼

早速のご回答ありがとうございました。元の複雑なコードを単純化したつもりが、自分の理解不足で質問したかったところと別の場所でもご指摘を受けてしまい、どうもすみません。元のコードではご指摘の通り、 TestClass* pClass = new TestClass; などとなっているはずです。 元のコードがご指摘の通りになっているとすると、intDataTestの実体は開放されないので、Funcを何度呼び出しても他でm_intDataを書き換えなければ、同じ値が入っているということなのでしょうか。 Funcを抜けた時の私の理解は間違っているとして、本物コードでの、2度目のFunc呼び出しでは、intDataTestがすべて0になっているのは、(質問には出てない)別の箇所と考えられますか? お手数おかけして申し訳ありませんが、よろしくお願いします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 【C++】関数ポインタの代入

    C++の関数ポインタについて質問です。 下記のように関数ポインタを宣言し、3通りの代入を行ってみました。 (3)のように関数名の頭に&を付けた場合と(2)のように&を付けなかった場合で 全く動きが同じになってしまうのですが、何故なのでしょうか? ------------------------------------------ #include "stdafx.h" #include <iostream> using namespace std; void Func1(){ cout<<"Func1が呼ばれました。"<<endl; return; } int main() { //(1) void (*fp1_1)(); fp1_1 = Func1; fp1_1(); //(2) void (*fp1_2)()=Func1; fp1_2(); //(3) void (*fp1_3)()=&Func1; fp1_3(); getchar(); return 0; }

  • C言語 動的確保とポインタ参照について

    以下のようなプログラムについて質問させて頂きます. main文で宣言されているaに配列を動的確保したいのですが,funcの関数内でaにアクセスする方法が分かりません.*(a[i])かな,とは思ったのですが上手く動作しませんでした. func実行後のmain文からはaの要素にアクセス出来るので,確保自体は成功していると思うのですが,如何でしょうか・・・? 宜しくお願いします. void func(int **a) {  *a = new int[32]; for(int cnt=0; cnt<32; cnt++) { /* aの配列の要素に値を代入したい(a[i] = i のように) */ } } int main(void) { int *a = NULL; func(&a); }

  • C++ ポインターの使い方について

    配列を作成し、その先頭のアドレスを返して、捜査したいのですが、出力が思い通りになりません。 for文で作成していたのですが、おかしいと思い、まったく同じprintf文を突っ込んでみたところ、2回目以降値がおかしなものとなりました。 これはどうして起こるのでしょうか? int* Generator::getData() { int data[32]; int* data_top_addr = &data[0]; for(int i=0; i<32; i++) { data[i] = i; } return data_top_addr; } void main() { Generator generator; int *data_top_addr; data_top_addr = generator.getData(); printf("%d\n", *data_top_addr); printf("%d\n", *data_top_addr); printf("%d\n", *data_top_addr); } 実行結果 0 6822320 6822320

  • ポインタの代入の省略について

    下記のプログラムにおいて、 Base* const sensor(mSensors[0]);は Base* const sensor = mSensors[0]; と同意だということなのですが、 C++のこのようなポインタの代入の記述法(?)について 書かれた参考書をもっておらず、最初かなりとまどいました。 このような記述法に名前(XX法)はついているのでしょうか? またこのような表記法について説明がなされている参考書または Webページがあればご教示いただけないでしょうか? よろしくお願いします。 #include <stdio.h> class Base { protected: public: Base(int n); void func(); }; Base::Base(int n) { printf("hello, world\n"); } void Base::func() { printf("func is called\n"); } int main(void) { Base* mSensors[2]; mSensors[0] = new Base(5);       Base* const sensor(mSensors[0]); sensor->func(); return 0; }

  • JAVAでCの関数ポインタのようなことをするには?

    CのプログラムをJAVAに移植しています。関数ポインタのプログラムを移植したいのですがやり方がよく判りません。interfaceを実装するとできるようですが・・・ 以下のCプログラムをJAVAに移植する方法を教えてください。 #include <stdio.h> int func(int , int); int main() { int (*po)(int , int) , i; po = func; i = (*po)(10 , 3); printf("%d" , i); return 0; } int func(int i , int j) { return i + j; }

    • ベストアンサー
    • Java
  • Cのポインタについて

    int howiwork(char *s, char **tab) { int i; if( s == NULL ) return ERROR; for ( i = 0;*tab;tab++,i++) if(! strcmp(s,*tab)) return i; return ERROR; } このプログラミングの機能を教えていただきたいのですがお願いします。

  • グローバル変数について

    ◎1--------------------------------- #include<stdio.h> void func(void); int glb; int main(void) { int a=20; glb=30; printf("main a=%d glb=%d\n",a,glb); func(); return 0; } void func(void) { int b=88; printf("func b=%d glb=%d\n",b,glb); } ------------------------------------- ◎1の実行結果----------------------- main a=20 glb=30 func b=88 glb=30 ------------------------------------- ◎2--------------------------------- #include<stdio.h> void func(void); int glb; int main(void) { int a=20; func(); printf("main a=%d glb=%d\n",a,glb); return 0; } void func(void) { int b=88; int glb=30; printf("func b=%d glb=%d\n",b,glb); } ------------------------------------- ◎2の実行結果----------------------- func b=88 glb=30 main a=20 glb=0 ------------------------------------- 以上2つのプログラムで、◎1は参考書を参考に作成したものです。 ◎1のプログラムで、グローバル変数glbの値をmain( )関数内で設定していたので、次に◎2のようにfunc( )という関数プロトタイプ内で、グローバル変数glbの値を設定し、main( )関数内のprintf文でも表示させようと思ったら、「glb=0」となってしまいました。 なぜこのようになってしまうか、教えてもらえたら嬉しいです。

  • 関数ポインタについて

    C言語の関数ポインタの問題で以下のような問題で、実際に解いて、プログラムを動かしてみてみました。 正常に動作したのですが、この回答では満点はもらえませんでした。 このほかに良い解答例などありましたら、教えていただけないでしょうか。 どうかよろしくお願い致します。 [問題]次の※1・※2を埋めなさい(「func1」,「func2」は解答に含まれないように書くこと)。 #include <stdio.h> void func1() { printf("func1\n"); } void func2() { printf("func2\n"); } void func(int no) { void (*func[2])(void) = {func1, func2}; /* ※1 (*func[no])() */; } int main() { /* ※2 func(1) */; return 0; } 実行結果:func2

  • c言語で大きな値の階数を求めたいのですが

    c言語で関数を用いてn!を求めるプログラムを作ったのですが、 nの値が大きくなると0という値になってしまって正しい値が出てきません。 プログラムをどの様に修正したらきちんとnの値が大きくなっても 正しく値が表示されるでしょうか? ソースはこちらです。 #include <stdio.h> int func(int i); int func(int i){ if(i == 0) return 1; else return (i*func(i-1)); } void main(){ printf("%d",func(90)); /*90!を求める*/ } よろしくお願いします。

  • 2つのコードの違いについて

    以下は間違ったコードですが、コード1では”不正な処理~”が出ますがコード2では出ません。 同じコードに思えるのですが、どうして違いが出るのですか? <コード1> void func(void) {  void *buf1[10];  static int i;  for (i = 0; i < 100; i++) {   buf1[i]=0 ;  } } int main(void) {  int buf[1000];  func();  return 0; } <コード2> int main(void) {  int buf[1000];  void *buf1[10];  static int i;  for (i = 0; i < 100; i++) {   buf1[i]=0 ;  }  return 0; }