• ベストアンサー

ポインタを引数に渡してメモリ領域をとる

C++でアプリケーションを作っています。 メモリ領域を動的に確保するコードを書いているところなのですが、 int *pr; // ポインタ kakuho(pr,100); // 新たにメモリ領域int100個分確保し、先頭番地をprに返す関数 というコードを作りたいのですが、 kakuho(int *pr,int num){ pr=new int[num]; return; } このようなプログラムを書いてVisual C++.NETでコンパイルすると、コンパイルは成功するのですが、実行時に Run-Time Check Failure #3 - The variable 'pr' is being used without being defined. このメッセージの意図することがよくつかめぬまま、ここで開発が止まっています。 どういう意味なのか、また、解決するにはどのようにしたらよいか教えてください。

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

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.5

「変数 'pr' が定義される前に参照されている」と言うエラーです。 kakuho(int *pr,int num){  pr=new int[num];  return; } このように書いた場合、prはグローバル変数ではなく、関数に渡された引数prを初期化しています。そして、引数prは関数を抜けた瞬間に消えて無くなります(つまり、初期化したのが「無かった事」にされる) 「C、C++では、引数は実体渡しされない。一時的な変数が作成され、値が一時変数にコピーされてから関数が呼ばれ、関数から抜けると同時に、引数は自動的に破棄される」と言うのを覚えておいて下さい。 関数内で何かの変数を初期化する(変数に値を設定して来て欲しい)場合は、変数のアドレスを渡す必要があります(変数の実体にアクセスする為の手掛りを渡す) 呼び出し側の int *pr; kakuho(pr,100); では、アドレスが未定義のままのprを引数に渡そうとしているので「変数 'pr' が定義される前に参照されている」と言う事になります。 「引数に渡す=参照」です。「引数に渡す」とは「一時変数を作成して、その一時変数に値をコピーする」と言う事なので、値をコピーしようとして「参照」を行う事になります。 以下のように書き替えて下さい。 int *kakuho(int num); main() {  int *pr;  pr = kakuho(100);  return 0; } int *kakuho(int num) {  return new int[num]; } 以下のような記述でもOKですが、関数からの戻り値を使わない分、無駄が増えます。(こちらの方が、質問者さんが書いたソースコードに近い) void kakuho(int **p,int num); main() {  int *pr;  kakuho(&pr,100);  return 0; } void kakuho(int **p,int num) {  *p = new int[num]; }

noname#129397
質問者

お礼

回答ありがとうございました。サンプル通りにやるとうまくできました。 ところで、kakuho()の中で確保した領域に値を代入するにはどうすればよいのでしょうか? void kakuho(int **p,int num) { *p=new int[num]; *(p+0)=1; // 先頭の領域に1を格納したつもり *(p+1)=2; // 2番目の領域に2を確保したつもり } とすると int *u; kakuho(u,20); // 20個分確保 cout << u[0] << endl; cout << u[1] << endl; とすると、 1 4301832 と、1番目はうまくいっていますがそれ以降がうまくいっていません。 どうすればよいのでしょうか(皆さんの回答を理解しきっていないということになってしまいますが…)

その他の回答 (6)

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.7

void kakuho(int **p,int num) { *p=new int[num]; *(p+0)=1; // 先頭の領域に1を格納したつもり *(p+1)=2; // 2番目の領域に2を確保したつもり } 上記プログラムはメモリを破壊します。 引数pは「intのポインタへのポインタ」ですから *p=new int[num]; (*p)[0]=1; (*p)[1]=2; と書く必要があります。 判りやすく書き直すと void kakuho(int **array_ptr,int num) {  int *array; // 配列の先頭を保持する一時変数  array = new int[num]; // 配列を確保  *array_ptr = array; // 確保アドレスを呼出元に返す  array[0]=1; // 先頭の領域に1を格納 //(*array_ptr)[0]=1;でも同じ  array[1]=2; // 2番目の領域に2を格納 //(*array_ptr)[1]=2;でも同じ } となります。

  • keroro001
  • ベストアンサー率23% (71/304)
回答No.6

あぁ答え書いてる間に回答出てたわ。。。orz じゃあ1つだけ。 mallocは使ってはいかんのですか? ANSIレベルで定義されているし、簡単だと思うのですが・・・

  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.4

変数varの内容を変更する関数であれば、引数に渡すものは変数varへのポインタか変数varの参照である必要があります。 関数kakuhoの中で変数prに何らかの値を設定する、つまり変数prの内容を変更したいのですよね。 > kakuho(pr,100); という文は関数kakuhoに「変数prの値」を渡しいます。これでは変数prの内容は変わりません。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.3

ポインターに確保したメモリのアドレスをセットする為には、以下のようにします。 int *pr; // ポインタ kakuho(pr,100); を kakuho(&pr,100); // pr->&pr kakuho(int *pr,int num){ pr=new int[num]; return; } を kakuho(int **pr,int num){ //*pr -->**pr *pr=new int[num]; //pr --> *pr return; } 上記のように変更して下さい。

回答No.2

/* target を 0 に設定する */ void set0(int target) { target = 0; } int x = 3; set0(x); これでxは0になるでしょうか? なりませんよね。 void set0(int* target) { *target = 0; } int x = 3; set0(&x); これならOK. ポインタについても同様です。 # '*'がひとつ足りないのです。

  • mithsc
  • ベストアンサー率33% (1/3)
回答No.1

その英文は分かりませんが、kakuho(pr,100);した時にprが不定値だからNULLを入れておけばエラーはなくなるんじゃないでしょうか。

関連するQ&A