質問: 関数にポインタを渡して動的確保する時について どうにも動的確保について間違っている気がするのでお尋ねいたします。 よくメモリを動的に確保する場合に私は次のようなプログラムを書きます ポインタを用意する(例えばint *p) mallocでメモリ確保 ポインタを関数に渡す(func(p)) 関数側でreallocし、値を代入する(p=(int *)realloc(p,sizeof(int)*num)) 関数呼び出し側で、その値を使う しかし、この方法を使うとどうにも関数を呼び出した際のポインタ(p)と、reallocした後のポインタ(p)の値が違うことがあり、値が不定になることがあります。 (reallocのメモリの確保の仕方のせいでしょうか) この使い方は恐らくどこか間違っていると思うんですが、いまいち納得のいく解決策が思いつきません。 例えばポインタを引数ではなく戻り値として得ればできますが、2つ以上のポインタについてはできません。 何卒ご教授のほどをよろしくお願いいたします。
回答: >ポインタを関数に渡す(func(p)) 提示されたコードはやりがちですが、 非常に危険で間違ったプログラムです。 >2つ以上のポインタについてはできません。 これは int** sub( void ); のようなことを言っているのでしょうか? であれば可能ですが今回はあまり触れません。 以下は危険なコードサンプル #include #include int sub( int* p ); int main( int argc, char* argv[] ) { int ret; int *alloc; //allocをわざと初期化していません。 ret = sub( alloc ); if( ret ){ return -1; } //allocの中身は変わっていない為、不定 printf( "alloc = %#x\n", alloc ); //不定領域を開放 free( alloc ); return 0; } int sub( int* p ) { //pはallocの『中身』 //pに確保領域のアドレスが入る p = (int*)malloc( sizeof(int)*10 ); if( !p ){ return -1; } printf( "p = %#x\n", p ); //関数終了と共にpが破棄される return 0; } 上記のように引数に対して戻り値を設定する場合、 ポインタを渡さなければなりません。 上記のコードを修正するならば、 以下のようになります。 #include #include int sub( int** p ); int main( int argc, char* argv[] ) { int ret; int *alloc; //allocへのポインタを渡す ret = sub( &alloc ); if( ret ){ return -1; } //allocの中身は確保された領域へのポインタ printf( "alloc = %#x\n", alloc ); //正しい場所を開放 free( alloc ); return 0; } int sub( int** p ) { //pはallocへのポインタ //allocへのポインタの中身に確保領域のアドレスが入る *p = (int*)malloc( sizeof(int)*10 ); if( !p ){ return -1; } printf( "p = %#x\n", *p ); //関数終了と共にpが破棄される return 0; } 上記のコードはインデントを全角スペースにしているので、 コンパイルする時は半角に置換してください。