考虑这个小代码
#include <stdio.h>
#include <stdlib.h>
void* foo1(double bar)
{
double s2 = 0.5;
double s1 = bar/s2;
double toreturn[2] = {s1,s2};
printf("Outside main. Second value: %f\n", toreturn[1]); //this line is commented out for the second output. See below text
return toreturn;
}
int main()
{
void* (*foo)(double) = NULL;
foo = &foo1;
double bar = 2.12;
double* resp = foo(bar);
printf("In main. First value: %f\n", resp[0]);
printf("In main. Second value: %f\n", resp[1]);
return 0;
}
代码输出
Outside main. Second value: 0.500000
In main. First value: 4.240000
In main. Second value: 0.500000
,这是我的预期。但是,如果我注释掉打印指令(foo1
定义中的那个),我会得到这个输出:
In main. First value: 4.240000
In main. Second value: 0.000000
,这对我没有意义!对我来说,printf
命令可以改变变量的值似乎很奇怪。你能解释一下,请解释一下这种行为吗?
答案 0 :(得分:4)
这里的要点是你不能从函数返回一个本地数组。函数调用后,数组toreturn
使用的内存是空闲的。它可以被任何函数调用覆盖,包括printf
。
使用malloc
为函数中的数组分配内存,并返回指向已分配内存的指针,或将数组作为参数传递。
答案 1 :(得分:2)
您正在将void*
返回到堆栈上分配的数组。一旦函数foo1
返回,就不再分配该内存,因此使用main中的resp
是未定义的行为。
打印resp[0]
或resp[1]
是没有意义的,因为您有未定义的行为,所以您不应该期望任何特定的输出。
如果要在main中使用该数组,则应在main中声明它并将指针作为函数的参数传递给它:
double resp[2];
foo(bar, resp);
使用功能:
void foo1(double bar, double* resp)
{
double s2 = 0.5;
double s1 = bar/s2;
resp[0] = s1;
resp[1] = s2;
}
或者你可以用foo1
在malloc
内分配它并返回指向已分配内存的指针,但是你需要一个很好的方法来跟踪每次对malloc的调用,这样你就可以完成后请致电free
。