声称这里的代码不会返回正确的“Sum”,因为前面的PrintHelloWorld()
正在执行并取代了指针*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;
}
答案 0 :(得分:2)
这被称为Undefined Behavior并且它未定义,因此任何事情都可能发生,您无法实际预测行为,因为它取决于程序的结构及其运行条件。
如果启用编译警告,编译器必须警告您错误,返回本地变量的地址并尝试读取它的内容是未定义的行为,因为它在您从函数返回时已经解除分配。
由于它的未定义行为,任何事情都可能发生,例如,它可以正常工作&#34; 正确&#34;。
您正在返回本地变量的地址。存储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()
它仍然有效。
只有当它超出范围时才会被解除分配,在这种情况下没有发生。
答案 1 :(得分:0)
当您编写表现出未定义行为的代码时,发生未定义行为并不令人惊讶。使用特定体系结构上特定操作系统上的特定编译器,视频中的人正在使用它,他获得了你在那里看到的输出。
对于其他编译器,您可能会遇到其他形式的未定义行为。
例如,每次我尝试在计算机上运行时,此代码都会打印不同的输出值:
#include <stdio.h>
#include <stdlib.h>
int *Add(int *a, int *b)
{
int c = (*a) + (*b);
return &c;
}
int main()
{
int a = 2, b = 4;
int *ptr = Add(&a,&b);
printf("Sum = %d\n", *ptr);
}
[7:15pm][wlynch@watermelon /tmp] ./a.out
Sum = 1595243208
[7:16pm][wlynch@watermelon /tmp] ./a.out
Sum = 1392249544
[7:16pm][wlynch@watermelon /tmp] ./a.out
Sum = 1577798344
[7:16pm][wlynch@watermelon /tmp] ./a.out
Sum = 1340385992
[7:16pm][wlynch@watermelon /tmp] ./a.out
Sum = 1549621960
[7:16pm][wlynch@watermelon /tmp] ./a.out
Sum = 1572055752
[7:16pm][wlynch@watermelon /tmp] ./a.out
Sum = 1440946888
[7:16pm][wlynch@watermelon /tmp] ./a.out
Sum = 1604803272