由于x是一个局部变量,因此我认为当我尝试返回它时会出现错误。
对于这个问题的更一般的答案是:在C代码中错误的代码不一定会产生编译器或运行时错误。
如果你非常幸运,你会得到一个编译器错误或警告。
如果你幸运的话,在错误的代码运行时会崩溃(这经常发生在空指针错误中)。这很容易用调试器跟踪。
但如果你不幸的话,错误的代码可能会在以后导致崩溃(在看似无关的代码中),或默默地破坏一些数据结构(使你的程序表现出奇怪的方式而没有崩溃),甚至表现得很好(直到你在其他地方添加看似无害的代码,或使用不同的编译器,或同一编译器的不同版本,或不同的编译选项)。
从技术上讲,你的代码在这一行具有未定义的行为:
int* c = func1()
你正在使用
func1
的返回值(将其写入
c
中)。但该值是
func1
中的局部变量的地址,当
func
返回时,该变量已经不存在了。这意味着返回值是一个无效的指针,仅仅是使用这样的指针就会导致未定义的行为(你甚至不需要解引用它)。
printf("%d\n", *c); // output: 123123
这行代码既使用了错误的指针(从c
读取它),又对其进行了解引用。但程序似乎仍然正常工作。
printf("%d\n", *c); // output: 0
这似乎是一个无害的添加,但这一行并没有产生预期的输出。现在看起来像是静默数据损坏。
请注意,这些都不是保证的。使用不同优化设置的不同编译器或相同编译器可能会产生行为不同的代码。就标准而言,编译器必须生成与C代码的可观察行为匹配的代码。但是,行为未定义的C代码可能会导致任何事情发生;对于编译器可以对其进行什么操作没有任何保证或限制。
printf
的调用在某个时候覆盖了该存储空间。这是一个错误。只需修复它并继续生活。 - Tom Karzesc
的赋值是未定义行为。 - chux - Reinstate Monica