【发布时间】:2021-04-12 18:10:50
【问题描述】:
我知道返回指向局部变量的指针不是一个好主意,因为用于该变量的堆栈将被重用。因此:
#include <stdio.h>
int *func(){
int x = 10;
return &x;
}
int main(){
printf("%p\n",(void*)func());
}
按预期打印(nil)。
但是,为什么我可以返回指向本地结构数据的指针? :
#include <stdio.h>
struct foo{
char c;
int *p;
};
int *func(){
struct foo f;
f.c = 'c';
int local = 10;
f.p = &local;
return f.p;
}
int main(){
int *b = func();
printf("%d\n",*b);
}
struct foo f 是函数func 中的local,因此每个局部变量都应该有相同的规则——即自动存储在堆栈中。我还没有查看它的汇编程序输出来确认这一点,但如果这个假设不成立,那么为什么要对结构类型进行特殊处理呢?在我看asm之前,struct foo的存储是否在堆栈中?
【问题讨论】:
-
不是不能返回指针。您可以返回指针。但是如果你使用指针,你可能会发现它不再指向相同的数据。
-
我不知道为什么你的第一个代码返回 null。这可能是因为编译器优化。尝试编译
-O0,然后它可能不会打印nil。 -
print '(nil)' as expected这是错误的期望。行为是未定义的,任何事情都可以发生。gccchooses to return NULL 在这种情况下,但这不是您可以或不应该依赖的东西。第二个例子也是undefined behavior,所以没有必要去思考为什么某事会发生或不发生,因为任何事情都是允许发生的。 -
这是未定义的行为,任何事情都可能发生,包括看似允许的事情。
-
@milanHrabos 是否简单地打印值是否是 UB,最好留给真正的语言律师来讨论。但无论如何,指针的值是未定义的,它可以是任何东西,所以“期望”任何特定的值都是错误的期望。
标签: c struct stack local-storage