• ベストアンサー

関数へのポインタ渡し

下位関数へポインタのアドレスを渡して(器を渡して) 内容を設定してもらうというのは、よくやることと おもいます。 そのポインタの領域は、普通は上位関数で実体を確保する と思っていたのですが、下位関数での実体確保することは 可能なのでしょうか? 対象はc言語です。 宜しく御願い致します。

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

  • ベストアンサー
回答No.4

> 下位関数の戻り値を上位関数が取得するのではなく > 下位関数へ引数で渡した場合は、実現できるのでしょうか? できます。*が一個増えますが。 void sub(int** aaa) { *aaa = malloc(...); ... } int* aaa; sub(&aaa); ... free(aaa); /* 必須 */

f_attck
質問者

お礼

再度の御回答ありがとうございました。 御手数をおかけしました。 大変助かりました。

その他の回答 (5)

  • Interest
  • ベストアンサー率31% (207/659)
回答No.6

こういう手はありですよね。 #include <stdio.h> #include <malloc.h> typedef struct{  char a;  int b; } Fuga; Fuga* Fuga_new(void) {  Fuga *this;  this = (Fuga *)malloc( sizeof(Fuga) );  this->a = 1;  this->b = 2;  return this; } void Fuga_print(Fuga *this) {  printf("a = %d, b = %d \n", this->a, this->b ); } void Fuga_delete(Fuga *this) {  free(this); } void main(void){  Fuga *fuga;  fuga = Fuga_new();  Fuga_print( fuga );  Fuga_delete( fuga ); } 動作確認済みです。 (参考) http://www.sage-p.com/process/cool.htm

f_attck
質問者

お礼

御回答ありがとうございます。 参考URLまで、助かりました。

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

上位関数で実体を一切確保せずにポインタを下位関数に渡し、下位関数で実体を確保することは不可能です。 上位関数で「ポインタを受け取るためのポインタ」を用意し、それを下位関数に渡すことは可能です。その場合、上位関数では「ポインタを受け取るための場所」という実体をまず確保し、そのポインタを下位関数に渡すことになります。

f_attck
質問者

お礼

御回答ありがとうございます。

回答No.3

int* do_something() { int* result = malloc(sizeof(int)*N); .... return result; } ただし、受け取った結果は速やかに free すべし。

f_attck
質問者

補足

すみません 記述されているのは、下位関数ですよね? 下位関数の戻り値を上位関数が取得するのではなく 下位関数へ引数で渡した場合は、実現できるのでしょうか? 下記のコーディングのように実施した場合 sub()コール後にaaaの参照は可能でしょうか? int main() { int* aaa = NULL; sub(aaa); return 0; } int sub(int *aaa) { aaa = malloc(); }

  • 6dou_rinne
  • ベストアンサー率25% (1361/5264)
回答No.2

可能です。 ただ、その実体が不要になったときの開放を考慮していないとメモリリークになる可能性もあります。

f_attck
質問者

お礼

御回答ありがとうございます。

  • entree
  • ベストアンサー率55% (405/735)
回答No.1

下位関数で確保しても、その関数を終了したら開放されてしまいますね。 スタック変数の領域は上位関数の変数から積み上げられるように確保されていくので、そのようなことは無理だと思います。 どうしてもそのようなことをしたいのであればヒープ領域を使う以外ない (malloc, calloc) と思います。 専門家ではないので、間違っていたらごめんなさい。

f_attck
質問者

お礼

御回答ありがとうございます。 確かにスタックのみでは無理ですね。。。

関連するQ&A

  • 関数へのポインタ渡しでの配列の初期化について

    はじめまして、C言語の基本的な質問をさせてください。 C言語で、外部関数へポインタで引数を渡す場合に、 関数に渡されるのはアドレスですよね? で、渡された関数側でそのポインタの配列の初期化を するときにはアドレスだけの情報だと、要素数がいくつ あるか分からず、領域の破壊をしてしまいそうな気が するのですが?いかがでしょうか? また、関数かなんかで、配列の要素数が分かる関数が あったような気がするのですが、それもアドレスだけ でわかるのでしょうか?

  • ポインタによる関数への配列渡し

    林晴比古さんの「新C言語入門」でC言語を勉強している初心者です。 現在ポインタの勉強をしています。色々教科書の文例等をポインタで書くとどうなるか試しております。 上書P200練習問題2に「配列の最大値を返す(その際配列の長さを渡す)」プログラムがあり、それをポインタで渡すプログラムに直してみました。 仮引数に「maxdata」を設定し、そのアドレスを関数側に渡し、関数側ではポインタとして受け取る(そうすれば関数側からはreturnで値を返す必要がない)、と考え、下記のように書いてみました。 #include <stdio.h> void max_of_array(int n[], int len, int *ans); int main(void) { int dt[6] = {50,20,80,30,10,40}; int maxdata; max_of_array(dt,6,&maxdata); printf("最大値=%d\n", maxdata); return 0; } void max_of_array(int n[], int len, int *ans) { int i; ans = &n[0]; for (i=1; i<len; i++){ if (*ans < n[i]) *ans = n[i]; } } しかしコンパイルすると、何故か「最大値=1」となってしまいます。(正しくは80です) 他にも色々試してみましたがうまくいかず、かなり考えてみたのですがどうしても分かりません。お分かりの方、どうすれば正しくなるのが教えてください、よろしくお願いします。

  • 関数ポインタの利点

    こんにちは。 C言語初心者ですが今勉強中です。 その中でポインタについては理解できたのですが、 関数ポインタの利点、使うべき所などが理解できません。 ポインタの基本は理解しています。 値渡し、アドレス渡しも理解しています。 関数ポインタを使うと何がいい、またはどんなとき使わなければならないのか 教本を読んでいてもさっぱりわかりません。 サンプルプログラムを打っても何のために使ってるのかわからないです。 どなたか教えていただけませんでしょうか? よろしくお願いします。

  • 続ポインタによる関数への配列渡し

    連続での質問すみません。 林晴比古さんの「新C言語入門」で勉強している初心者です。 ポインタを勉強中で、色々な例文をポインタで書けるかどうか 試しております。 上書P199に「安全な数値入力を行うプログラム」が出ています。 これは入力時問題点を抱えるscanfに入力させるのでなくchar型に入力させ、 それをint型に変換して出力するという内容で、案内メッセージも関数内で表示することになっています。 以下そのプログラムを引用します。 #include <stdio.h> #include <stdlib.h> int getint(char msg[]); int main(void) { int n; n = getint("数値を入力してください:"); printf("入力した数値=%d\n",n); return 0; } int getint(char msg[]) { char ss[80]; printf("%s",msg); gets(ss); return atoi(ss); } (以上林晴比古氏「新C言語入門」P199より引用) これをポインタによって書き換えようとしているのですがうまくいきません。 「本引数として主文でint型のnを設定し、それを関数側のchar型のssをポインタにして 仮引数として受け取れば、最後にreturnで返さなくても、参照できるのでないか」 と思い色々試してみましたがうまくいきません。 どうもコンパイルのエラーを確認すると型が違うので駄目なようです。 なるほどそれはそうでした… それ以外の方法も色々試してみましたが、結局うまくいきませんでした。 どのようにすればポインタでは上の文章を表現できるのでしょうか。 (あるいは表現出来ないのでしょうか) お分かりの方、よろしくお願いします。

  • c言語のmalloc関数、またrealloc関数

    c言語のmalloc関数は確保するメモリの領域を、配列としてのみしか処理出来ないのですか。 つまり、malloc関数で確保したメモリの領域を変数、また多次元配列、また構造体としては処理出来ないのでしょうか。 c言語のrealloc関数は以前の確保したメモリの領域から、確保し直したメモリの領域の場所が変わるかもしれないという事ですが、この場合の場所が変わるという意味は、メモリの領域のアドレスが変わるという事でしょうか。 また、以前の確保したメモリの領域に代入していたデータが使用出来なくなるという事でしょうか。

  • 関数へのポインタ

    超初心者です。 C言語を使ってsin波を生成して音を鳴らそうとしているのですが・・ネットで調べてもよくワカリマセン・・ 超初心者な私でも理解できるようなサイトを教えて下さい. また、関数へのポインタも勉強しているのですが, char *(*func)(void); といったchar 型へのポインタを返す関数へのポインタというのがあったとして,関数へのポインタは理解できたのですがさらにchar 型へのポインタとなると一体これが何を指しているのかさっぱりで・・・・ ご協力お願いします.

  • JNAで関数ポインタの表し方

    JNAで関数ポインタの表し方 JNAを利用してC言語の関数をJavaで利用したいのですが、その関数の引数に関数ポインタが含まれていて、使い方が分かりません。 関数ポインタ型のJavaのマッピングはどうすればいいのでしょうか? つまりJavaの特定のメソッドをその関数内からコールバックさせたいです。

  • void型へのポインタ

    というのがC言語にありますよね? このvoid型へのポインタというのは、 どのようにイメージすればいいのでしょうか? 例えばchar型へのポインタなら、 指している領域は 1バイトの領域ですよね? ではvoid型は? また malloc関数を 使って char *p; p=(char *)malloc(1000); とするとでchar型にキャストしているから、 1個1バイト分の領域が1000個用意して、 先頭アドレスをpに格納するのですよね? では、 int *q; q=(int *)malloc(1000); としたら、用意されるのは、int型にキャストしているから 1個2バイト分の領域が500個用意されるのでしょうか? お願いします。

  • 関数ポインタについて

    C言語によるUNIXシステムにプログラミング入門という本を読みながらC言語を勉強しています。 しかし、サンプルとして提示された下記の内容の意味がわかりません。 分からない箇所が「関数ポインタ」と呼ばれるものがついているということが分かった程度で、どういう意図で記述されているのかがわかりません。 分からないプログラムの処理内容は、ファイル内のデータを16進数で表示するというものです。 分からない箇所を記します。 #include <stdio.h> #define BUFF 17 /*buffer*/ #define ERR -1 /*system call error*/ void usage(void); /*put usage message*/ char *command_name /*command name*/ FILE *fpin; /*file pointer*/ main(int argc,char *argv[ ]){ char *rindex(const char*s,int c); /*末尾から文字列検索*/ void hexdump(void); ... ... } void hexdump(void){ ... ... } void usage(){ ... ... } 不明なのは、main関数の中の char *rindex(const char*s,int c); /*末尾から文字列検索*/ void hexdump(void); です。 Cについて、不明なところが多いので、利用する関数は使う前に宣言しなければいけない程度の理解ですが、そうだとしてもusageメソッドはmain関数の外であるのに、rindexとhexdumpは何故main関数の中で宣言されているのでしょうか。 上記の不明点とは別で、rindexの前にポインタが付いていると思うのですが、hexdumpやusageにはついていません。 知人からは、関数までのポインタを返すとのことでしたが、用途もいまいち理解できません。 全てではなくてもいいので、ヒントをいただけるとうれしいです。 よろしくお願いします。

  • 二次元配列とポインタについて

    関数内の変数宣言にて (1) int *( p[ 5 ] ); (2) int ( *p )[ 5 ]; の違いを教えて下さい。 (1)は *p[ 5 ] と同義のようで int実体のポインタとなるp[ 0 ]からp[ 4 ]の 配列が作られるようです。 つまり領域に作られるのは 5つの連続したint型へのシングルポインタであり その他のint実体やダブルポインタは 領域に作られないと認識しております。 (2)との違いが分かりません。 領域では実際に何が作られるのかという点と このように演算の優先順位がある場合に どのような順番で解釈すればよいのかという点について ご説明頂けると助かります。 ではよろしくお願いします。

専門家に質問してみよう