c++ - 为什么这运行良好? (访问范围外变量的地址)

标签 c++ pointers memory-management scope memory-access

<分区>

为什么它运行良好? (而且连续好几次..)

double* p(nullptr);
cout << p << endl;      // "00000000"
{
    double d(82.);
    p = &d;
}
cout << p << endl;      // "0029FD98"

// Naughty, dirty, sneaky..
// .. but rather *pure* curiosity after all.. u_u
cout << *p << endl;     // "82", first surprise
*p = 83.;               // (getting further down the hole..)
cout << *p << endl;     // "83", and I almost feel disappointed. :(

难道 d 应该超出范围并且 0029FD98 被释放了吗?为什么我的操作系统不生气?我只是 super 幸运吗?

最佳答案

您正在调用未定义的行为。根据 C++ 规范,这里可能发生任何事情。未定义的行为是一件非常糟糕的事情,因为它意味着您无法知道您的程序可能会做什么不惜一切代价避免它。

在使用特定编译器的特定平台上,这可能有效,因为变量是在堆栈上分配的,并且在程序运行时堆栈内存不会(通常)释放。因此,0029FD98 指的是分配的内存区域(在本例中为堆栈)内的地址。一旦您调用一个函数,这个位置可能会被该函数需要堆栈空间的任何内容覆盖。

在其他系统和/或编译器上,局部变量和/或堆栈的行为或实现可能不同,这可能会输出一些随机数,或者可能会崩溃,或者可能会输出莎士比亚的集体作品。

关于c++ - 为什么这运行良好? (访问范围外变量的地址),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24967965/

相关文章:

c++ - 如何在 C++ 中查找另一个字符数组?

c++ - 使用 rundll32 运行 C++ DLL - 缺少条目

c++ - 指针++,未定义的行为

iphone - Objective-C 中的内存管理

c++ 应用程序无法分配比某个限制更多的大页面

c++ - 为什么 std::set 和 set::map 的默认构造函数需要堆分配?

c++ - &a[n] 是否有效,其中 n 是数组的大小?

c++ - 在构造函数中终止对象创建

c++ - C++中的抽象类指针

c - 如何正确重新分配内存?