你想做的很好,但你的代码没有这样做——main
永远不会看到分配的内存。的参数使用函数调用中传递myArray
的myFunction
值进行初始化,但此后修改它不会修改main
.
它出现在您myFunction
始终返回的代码片段中0
。如果是这样,那么修复代码的最明显方法是返回myArray
(并且不带参数)。然后调用main
看起来像myArray = myFunction();
。
如果myFunction
实际上已经使用了它的返回值,那么您可以传入一个指向 的指针,double*
并将地址写入该指针的引用。这就是 Ed Heal 的回答。该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,可能使用不同的编译器,并且两者不使用兼容的malloc/free
.