为何传递双指针存局部变量地址无段错,返回该地址却触发段错?
关于悬空指针的疑问
我理解悬空指针(dangling pointer)的概念,func2返回的是已释放内存的地址。但在func1中,我们通过传递双指针来存储局部变量的地址,这不也属于悬空指针的情况吗?
以下是测试代码及输出:
#include <iostream> void func1(int **x){ int z = 10; *x = &z; } int *func2(){ int z=11; return &z; } int main() { int *a; func1(&a); std::cout << *a << std::endl; int *b = func2(); std::cout << *b << std::endl; return 0; }
输出:
10 段错误
解答
没错,func1和func2的做法都会产生悬空指针,两者的行为都属于C++标准定义的未定义行为。
- 函数
func1里的局部变量z在函数执行完毕后,其栈内存会被回收;func2同理,局部变量z的内存也会在函数返回后被释放。此时main里的指针a和b都会指向已经被释放的内存区域,成为悬空指针。
至于运行时第一个输出是10,第二个触发段错误,这正是未定义行为的典型表现:
- 栈内存被释放后,不会立即覆盖原有数据,第一次访问
*a时,恰好旧值还没被修改,所以能输出预期结果; - 而第二次访问
*b时,这块内存可能已经被后续操作(比如函数返回后的栈帧清理、std::cout的内部操作)覆盖或者被标记为不可访问,从而触发段错误。
这种行为完全依赖于编译器、操作系统和运行环境,没有任何规律可言,绝对不能依赖这种“偶然正确”的结果。
内容的提问来源于stack exchange,提问作者Manan Chawla
相关产品推荐
相关产品推荐

