printf更改了值

时间:2014-10-28 16:14:54

标签: c function pointers printf

考虑这个小代码

#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命令可以改变变量的值似乎很奇怪。你能解释一下,请解释一下这种行为吗?

2 个答案:

答案 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;
}

或者你可以用foo1malloc内分配它并返回指向已分配内存的指针,但是你需要一个很好的方法来跟踪每次对malloc的调用,这样你就可以完成后请致电free