通过向函数传递双 ptr 来存储本地 var 的地址不会导致 seg 错误,但返回该 var 的地址会导致 seg 错误。为什么?[复制]

Storing address of local var via passing a double ptr to function does not cause a seg fault but returning address of that var causes seg fault. Why? [duplicate]

提问人:Manan Chawla 提问时间:7/24/2022 更新时间:7/25/2022 访问量:37

问:

我理解悬空指针的概念,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 SEG故障

C++ 空指针

评论

0赞 user12002570 7/25/2022
该程序具有未定义的行为,这意味着任何事情都可能发生,包括但不限于程序提供预期的输出。程序可能会崩溃。但永远不要依赖具有 UB 的程序的输出。请参阅此处的相同解释。

答:

2赞 user17732522 7/24/2022 #1

是的,当您取消引用它们时,两者都是悬空指针,因此任何一个取消引用都会使程序无效。ab

但是,取消引用悬空指针会导致未定义的行为。这意味着对任何特定行为都没有任何保证。无法保证段错误。无法保证特定输出。不能保证它看起来不会像访问指向生存期外变量“有效”的悬空指针。

3赞 Andreas Wenzel 7/24/2022 #2

在这两种情况下,您都在取消引用悬空指针,这会调用未定义的行为

这意味着您不能依赖任何特定行为。您可能会遇到分段错误,或者您的程序可能按预期工作,或者可能会发生其他事情。在不同的编译器上,行为可能不同。即使在同一个编译器上,行为也可能不同,具体取决于编译器设置,例如优化级别。此外,只需将编译器更新到新版本就可能导致行为发生更改。

询问为什么在调用未定义的行为时没有收到分段错误并不是一个有意义的问题。这就像当你闯红灯时驾驶你的车通过十字路口,然后问为什么你没有与另一辆车相撞。当你违反规则时,你不能依赖任何具体的事情发生。

您可能想阅读这个类似的问题:

是否可以在其范围之外访问局部变量的内存?