有人声称,由于前面的PrintHelloWorld()
,这里的代码不会返回正确的“Sum”。正在执行并替换指针 *ptr
的值指着。但是,每次运行它时我都会得到正确的值,甚至运行 PrintHelloWorld()
在打印 *ptr
之前运行十几次或更多次。
那么为什么即使指针指向一个已从堆栈中弹出的值,我的代码仍然可以工作并返回该值?
#include <stdio.h>
#include <stdlib.h>
void PrintHelloWorld()
{
printf("Hello World\n");
}
int *Add(int *a, int *b)
{
int c = (*a) + (*b);
return &c;
}
int main()
{
int a = 2, b = 4;
int *ptr = Add(&a,&b);
PrintHelloWorld();
printf("Sum = %d\n", *ptr);
return 0;
}
最佳答案
这就是 Undefined Behavior而且它是未定义的,因此任何事情都可能发生,您实际上无法预测行为,因为它取决于程序的结构及其运行条件。
如果启用编译警告,编译器必须警告您错误,返回局部变量的地址并尝试读取其内容是未定义的行为,因为当您从函数返回时它已经被释放。
由于它是未定义的行为,所以任何事情都可能发生,例如,它可以“正确地工作”。
您正在返回局部变量的地址。变量c
存储 *a + *b
的结果的位置是函数 Add()
的本地函数并且具有自动存储期限。
这意味着,当函数返回时,它会被释放。由于您将地址返回给它,并且它已被释放,因此尝试打印它只会输出垃圾。
试试这个看看
int *Add(int a, int b, int *c)
{
*c = a + b;
return c;
}
然后在 main()
int main()
{
int a = 2, b = 4, c, *ptr;
ptr = Add(a, b, &c);
printf("Sum = %d\n", *ptr);
return 0;
}
如您所见,您通过了 c
的地址并在 Add()
里面修改它功能。
c
变量是 main()
的局部变量因此将其地址传递给 Add()
修改它,然后在 main()
中读取它完全没问题,因为在main()
中它仍然有效。
只有当它超出范围时才会被释放,但在本例中没有发生这种情况。
关于c - 作为函数返回的指针不会像声称的那样被覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29724277/