为什么这段返回栈局部变量指针的C++代码没有触发segmentation fault?
#include<iostream> using namespace std; char* func(){ char ch='a'; char *ptr=&ch; return ptr; } int main() { char *ptr=func(); cout<<*ptr; }
你遇到的是C++标准明确定义的未定义行为,未定义行为不存在「应该出现段错误」的强制要求,它的表现完全取决于运行环境、编译器实现、甚至是同环境下的运行时状态,任何结果都是符合规则的。你遗漏的关键点有三个:
- 栈帧销毁的实际逻辑:func执行结束后,操作系统和编译器不会主动擦写对应栈内存的内容,只是会把栈顶指针回退到main函数的栈帧位置,标记原func栈帧占用的内存为「可复用」状态。这块内存只要还没有被后续的其他操作(比如调用新函数、声明新的局部变量)覆盖,原本存储的
'a'值就会保留下来,此时读取自然能拿到正确的值。 - 段错误的触发条件:段错误是操作系统层面的异常,只会在进程访问不属于自己的地址空间、或者对无权限的地址执行非法操作(比如写只读内存、访问用户态进程无权访问的内核地址)时才会触发。你返回的地址依然属于进程合法的栈内存映射范围,只是逻辑上已经废弃,所以操作系统不会拦截这次访问,自然不会抛出段错误。
- 这种未定义行为的不可靠性:你现在能正常输出
'a'只是巧合,只要稍微修改代码就会出现异常,比如在调用func后新增一个其他有局部变量的函数调用,新函数的栈帧会直接覆盖原func的栈内存,此时再读*ptr就会读到垃圾值,极端情况下也可能触发程序崩溃。
内容的提问来源于stack exchange,提问作者Arish Khan
相关产品推荐
相关产品推荐

