我不能返回指向局部变量的指针,但我可以返回指向c中局部结构数据的指针?

我不能返回指向局部变量的指针,但我可以返回指向c中局部结构数据的指针?,c,struct,stack,local-storage,C,Struct,Stack,Local Storage,我知道返回指向局部变量的指针不是一个好主意,因为用于该变量的堆栈将被重用。因此: #include <stdio.h> int *func(){ int x = 10; return &x; } int main(){ printf("%p\n",(void*)func()); } 函数func中的struct foo f是局部变量,因此每个局部变量都应该有相同的规则,即堆栈中的自动存储。我还并没有查看它的汇编程序输出来证实这

我知道返回指向局部变量的指针不是一个好主意,因为用于该变量的堆栈将被重用。因此:

#include <stdio.h>

int *func(){
    int x = 10;
    return &x;
}

int main(){
    printf("%p\n",(void*)func());
}

函数
func
中的
struct foo f
是局部变量,因此每个局部变量都应该有相同的规则,即堆栈中的自动存储。我还并没有查看它的汇编程序输出来证实这一点,但若这个假设不成立,那个么为什么要对结构类型进行特殊处理呢?在我看asm之前,struct foo在堆栈中的存储是吗?

您所有的示例都会导致。不再存在的对象的地址是不确定值(C116.2.4/2),尝试打印不确定值会导致不确定行为

有关不确定值的使用和语言规则的基本原理的更多标准参考和讨论,请参见


作为未定义的行为,您不应该期望任何特定的行为,例如
nil
或其他行为。

并不是您不能返回指针。您可以返回指针。但是如果使用指针,您可能会发现它不再指向相同的数据。我不知道为什么您的第一个代码返回null。这可能是因为编译器优化。尝试编译
-O0
,然后它可能不会按预期打印nil。
print'(nil)
这是错误的预期。行为是未定义的,任何事情都是允许发生的<在这种情况下,代码>gcc,但这不是您可以或应该依赖的东西。第二个例子也是,所以没有必要去解释为什么某些特定的事情发生或不发生,因为任何事情都是允许发生的。这是未定义的行为,任何事情都可能发生,包括一些看起来是允许的东西。@milanHrabos简单地打印值是否为UB,最好留给真正的语言律师来讨论。但在任何情况下,指针的值都是未定义的,它可以是任何值,因此“期望”任何特定值都是错误的期望。那么为什么呢。在第二个示例中,我得到了非常有效的
10
(在取消引用返回的指针之后)结果?UB将是空指针,但它不是。空指针仅位于第一个位置example@milanHrabos输出
10
可能是未定义行为的一种表现形式。请阅读我答案中的链接,了解“未定义行为”的含义。如果不是
10
@milanHrabos不正确,UB的表现形式将是。UB表示未定义的行为,而不是“与我的预期行为完全不同”打印未定义的值不会导致未定义的行为。您所引用的问题是指使用未初始化对象(其值不确定)的自动存储持续时间的值,而该值不采用其地址。它确实有未定义的行为,但不适用于此处。
#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);
}