为何C++中返回局部变量指针后未出现预期的悬空指针行为?
为什么返回局部变量地址的指针没有表现出悬空指针的行为?
先看你的代码:
#include <iostream> int* dont() { int num = 10; int* num_ptr = # return num_ptr; } int main() { int* a = nullptr; a = dont(); std::cout << *a; }
你的理解没错——a确实是悬空指针,之所以看起来能正常输出10,只是未定义行为的偶然表现,原因如下:
- 局部变量
num存储在栈内存中,当dont()函数执行完毕返回时,这块栈内存会被标记为可复用,但不会被立即清空或覆盖。此时a指向的就是这块已经被释放的内存区域,完全符合悬空指针的定义。 - 在Visual Studio 2022的默认Debug编译模式下,栈内存释放后不会立刻被改写,原来的值会暂时保留。你解引用
a时,刚好这块内存还没被其他操作占用,所以能输出10,但这只是巧合。 - 未定义行为的结果完全不可预测:如果在
a = dont();之后添加其他函数调用、变量声明,或者切换到Release模式编译,这块栈内存会被覆盖,此时解引用a要么得到垃圾值,要么直接导致程序崩溃。比如Debug模式下,VS有时会用0xCCCCCCCC标记释放的栈内存,此时解引用就会触发错误。
结论:永远不要返回局部自动变量的指针或引用,这种写法违反C++标准,属于严重错误,当前的正常输出只是不可依赖的偶然现象。
内容的提问来源于stack exchange,提问作者user22453137
相关产品推荐
相关产品推荐

