指向释放变量的指针更改地址

Pointer to deallocated variable changes address

此代码:

#include <iostream>

using namespace std;

int* fun()
{
    int a = 5;
    int* pointerA = &a;

    cout << pointerA << endl;

    return pointerA;
}

int main()
{

    int* p = fun();

    cout << p << endl;

    return 0;
}

打印以下内容:

0x[some address]
0

我理解变量a在函数fun()returns时被释放,但是为什么cout << p << endl;return0?它不应该仍然指向内存中的相同地址,即使变量在技术上不再存在了吗?这是编译器功能还是未定义的行为?

repro case

编辑:我找到了罪魁祸首。我正在使用 CodeBlocks,在这个项目的构建选项中,有一个标志 "optimize even more (for speed) [-O2]"。如果选中,我得到 0,如果我取消选中该标志,我得到相同的地址 0x[some address],这是预期的行为。

很抱歉没有提及我的 IDE。

这可能是一个编译器功能。在这种情况下,很容易看出由 fun 编辑的指针 return 将无效,因此进一步使用该指针将导致未定义的行为。如果您尝试不同的编译器,它可能会有所不同。例如。对我来说 Visual Studio 2012 年它 return 实际地址而不是 0.

访问 fun 的 return 值具有实现定义的行为,因为它 return 是一个无效的指针值(参见下面的引用,原因)。在特定平台上,它甚至可能会产生运行时错误。所以,p 的值也是实现定义的。很可能,它会变成无效的指针值,因此访问它是实现定义的。

basic.std/4:

When the end of the duration of a region of storage is reached, the values of all pointers representing the address of any part of that region of storage become invalid pointer values. Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior.