C言語関係掲示板

過去ログ

No.1028 引数として受け取ったポインタにmalloc

[戻る] [ホームページ]
No.13178

引数として受け取ったポインタにmalloc
投稿者---Mal-lock(2004/03/15 19:07:15)


配列の作成を行なう関数を作ろうと思ったのですが、
ポインタを受け取った関数の側でmallocによる割り当てを行なう処理を
書いたところ、呼び出し元の方に反映されませんでした。
戻るときに破棄されてる様子です。
細部を略すと以下のような感じのコードなのですが、printfの段階ではxはNULLになってます。
結局サイズの決定用にもう一つ関数を作ってmallocはmainで行なうことにしたのですが、
どうしてこうなのか理由がわかりません。ご教授願えないでしょうか。

#include<stdio.h>
#include<malloc.h>

int function(int *xx ) ;
int main( void )
{
  int *x = NULL ;
  function( x ) ;
  printf( "x[0] = %d\n", x[0] );
  printf( "x[1] = %d\n", x[1] );
  free ( x ) ;
}

int function( int *xx ) {
  /* 実際はここにサイズを決定する処理が入ります */
  xx = malloc( 2 * sizeof(double) ) ;
  xx[0] = 1 ;
  xx[1] = 2 ;
  return 0 ;
}


No.13180

Re:引数として受け取ったポインタにmalloc
投稿者---iijima(2004/03/15 21:26:36)


関数によって関数呼び出し元の変数の値を変更するには,その変数を指す
ポインタを引数とする必要があります.
この場合は変更しようとする変数がポインタですから,引数をポインタの
ポインタにすればできると思いますよ.
例えば:

int function( int** xx )
{
    *xx = malloc( 2 * sizeof(double) ); // なんでdoubleなのかよく分かりませんが...
    (*xx)[0] = 1;
    (*xx)[1] = 2;
    return 0;
}


No.13186

Re:引数として受け取ったポインタにmalloc
投稿者---RAPT(2004/03/16 02:04:06)


もしくは、
int *function(size_t count)
{
  int *p = (int *)malloc(count * sizeof(int));
  return p;
}

int main()
{
  int *pValue = NULL;
  pValue = function(10);
  free(pValue);
}
みたくするとか。



No.13201

Re:引数として受け取ったポインタにmalloc
投稿者---Mal-lock(2004/03/16 12:26:31)


>iijimaさん:

ご回答ありがとうございます。
sizeofの引数がdoubleになってたのはミスです。すみませんでした。

>関数によって関数呼び出し元の変数の値を変更するには,その変数を指す
>ポインタを引数とする必要があります.
>この場合は変更しようとする変数がポインタですから,引数をポインタの
>ポインタにすればできると思いますよ.

なるほど。ポインタを渡すのは参照渡しだからと短絡的に考えてましたが、
この場合コピーされずに参照されるのはNULLであって、
ポインタxは値渡しされてローカルなポインタxxが作られている訳ですね。
ここでNULLを変化させたとすれば(NULLは変数じゃないのでなんですが)反映されるけれども、
xxが指す先を変更しても、通常の仮引数に与えられた変化と何ら違いはないので
「function」の中でxxの指し示す先を変更して、その新しい領域に要素を代入しても、
戻る時にxxの値(参照先を示す値)は破棄されてしまうので意味ないと。
しかもmallocで確保したメモリブロックは、どこからも参照されない状態で残ったまま…

おかげさまで疑問が氷解しました。ありがとうございました。


>RAPTさん

ご回答ありがとうございます。
実は私も、戻り値をポインタにすることは考えました。
私がやったのは、pValueを引数に渡して、戻り値をまたpValueに入れるという方法でしたが。
ただ、戻り値として別に返したい値があったので使うには至りませんでした。
しかし考えてみれば、その方法が上手く行くという(確か行ったはず)時点で、
察しのいい人なら上のことに気付いても良かったんですよね…