那会错吗?如果是这样,为什么呢?输出是2500

时间:2015-12-26 16:07:14

标签: c pointers return-value

以下代码的输出为2500.它包含指针。有人可以给出正确的解释吗?为什么打印为2500?是通过指针声明还是有另一个原因?

#include <stdio.h>

/* Two functions include and they are operated by main function */

int *f(int x) {
    /* Creates an variable */
    int p;
    p = x;
    return &p;
}

/* Here the initialization of the function g */
int *g(int x) {
    /* Creates an variable */
    int y;
    y = x;
    return &y;
}

/* This creates two pointers called x and y */
int main() {
    int *x, *y;
    /* Here call the functions f and g */
    x = f(100);
    /* Here call the function g */
    y = g(2500);
    /* How does it print 2500? */
    /* print the value of x */
    printf("%d \n", *x);
    return 0;
}

3 个答案:

答案 0 :(得分:8)

您获得奇怪输出的原因是未定义的行为。您将返回自动局部变量的地址,该函数在函数到达时将不再存在。

虽然,可以根据函数调用的堆栈帧给出输出的说明。由于最后一次调用是函数g,并且传递给它的参数是2500,因此函数x的参数g在堆栈上分配,而2500是推到了堆栈。当此函数返回时,此值从堆栈中弹出(尽管返回到调用者后g的堆栈帧无效)并且它可能从其堆栈帧返回此2500

答案 1 :(得分:5)

在这两个函数中,您尝试在函数中返回 local 变量的地址。一旦函数完成执行并且控件返回给调用者,返回的地址就变为无效(即,变量超出范围),并且任何使用返回值的尝试都会调用undefined behavior

如果你必须从函数返回一个地址并在调用者中使用它,你将需要一个通过动态内存分配器函数分配内存的指针,如malloc()和family。

答案 2 :(得分:2)

我认为可以使用堆栈来解释所发生的事情。调用函数f时,堆栈的行为如下。 “ret”是返回地址。

2|   |    2|   |    2|   |    2| p |   
1|   | -> 1|   | -> 1|ret| -> 1|ret|
0|   |    0|100|    0|100|    0|100|

现在堆栈指针位于2,并返回该地址(p的地址)并将其分配给main中的* x。当它从f返回时,会弹出所有堆栈值,但实际发生的情况只是减少堆栈指针的值。因此推出的价值仍然存在。 再次调用函数g,堆栈如下。

2| p  |    2| p  |    2| p  |    2| y  |
1|ret | -> 1|ret | -> 1|ret | -> 1|ret |
0|100 |    0|2500|    0|2500|    0|2500|

与函数f相同,返回p的地址并在main中分配给* y。但请注意,它也是与p,2相同的地址。因此,* x和* y在main中都指向相同的位置。函数g将该地址的值设置为2500,因此* x和* y都打印2500。

希望这会有所帮助。 :)