あなたがしたいことは問題ありませんが、あなたのコードはそれをしません-main
割り当てられたメモリを見ることは決してありません。のパラメータmyArray
はmyFunction
、関数呼び出しで渡された値で初期化されますが、その後変更しても、内の同じ名前の無関係な変数は変更されませんmain
。
myFunction
これは、常にを返すコードスニペットに表示されます0
。もしそうなら、あなたのコードを修正する最も明白な方法は、代わりに戻ることですmyArray
(そしてパラメータを取りません)。その場合、呼び出しは次のようにmain
なりますmyArray = myFunction();
。
myFunction
実際にすでにその戻り値を使用している場合は、へのポインターを渡しdouble*
、そのポインターの参照にアドレスを書き込むことができます。これがEdHealの答えです。このdouble **
パラメーターは、関数が出力を格納するために使用する場所へのポインターであるため、「out-param」と呼ばれることがよくあります。この場合、出力はバッファのアドレスです。
別の方法は、次のようなことを行うことです。
size_t myFunction(double *myArray, size_t buf_len) {
int len=0;
...
/* compute len */
...
if (buf_len < len) {
return len;
}
/* populate myArray */
...
return len;
}
そうすれば、発信者は好きなようにメモリを割り当てることができます。一般的な呼び出しコードは次のようになります。
size_t len = myFunction(NULL, 0);
// warning -- watch the case where len == 0, if that is possible
double *myArray = malloc(len * sizeof(*myArray));
if (!myArray) exit(1);
myFunction(myArray, len);
...
free(myArray);
あなたが得たのは、発信者が便利な場所からメモリを割り当てることができるということです。あなたが失ったのは、発信者がより多くのコードを書かなければならないということです。
その自由を使用する方法の例として、発信者は次のように書くことができます。
#define SMALLSIZE 10;
void one_of_several_jobs() {
// doesn't usually require much space, occasionally does
double smallbuf[SMALLSIZE];
double *buf = 0;
size_t len = myFunction(smallbuf, SMALLSIZE);
if (len > SMALLSIZE) {
double *buf = malloc(len * sizeof(*buf));
if (!buf) {
puts("this job is too big, skipping it and moving to the next one");
return;
}
} else {
buf = smallbuf;
}
// use buf and len for something
...
if (buf != smallbuf) free(buf);
}
malloc
小さなバッファのみが必要な一般的なケースでは、これを回避することは通常不要な最適化です。これは、呼び出し元がメモリの割り当て方法について発言したい理由の一例にすぎません。より差し迫った理由は、おそらく別のコンパイラを使用して、関数が呼び出し元の関数とは異なるdllにコンパイルされ、2つが互換性のあるの実装を使用していないことである可能性がありmalloc/free
ます。