c++ - Visual Studio 如何处理已删除的指针,为什么?

标签 c++ pointers visual-studio-2012 memory-management delete-operator

我一直在阅读的一本 C++ 书指出,当使用 delete 运算符删除指针时,它指向的位置的内存被“释放”并且可以被覆盖。它还声明指针将继续指向相同的位置,直到它被重新分配或设置为 NULL

然而,在 Visual Studio 2012 中;好像不是这样的!

示例:

#include <iostream>

using namespace std;

int main()
{
    int* ptr = new int;
    cout << "ptr = " << ptr << endl;
    delete ptr;
    cout << "ptr = " << ptr << endl;

    system("pause");

    return 0;
}

当我编译并运行这个程序时,我得到以下输出:

ptr = 0050BC10
ptr = 00008123
Press any key to continue....

很明显,当调用delete时,指针指向的地址发生了变化!

为什么会这样?这是否与 Visual Studio 特别有关?

如果 delete 可以改变它指向的地址,为什么不自动将指针设置为 NULL 而不是一些随机地址?

最佳答案

我注意到存储在 ptr 中的地址总是被 00008123...

覆盖

这看起来很奇怪,所以我稍微挖掘了一下,发现了 Microsoft blog post包含讨论“删除 C++ 对象时的自动指针清理”的部分。

...checks for NULL are a common code construct meaning that an existing check for NULL combined with using NULL as a sanitization value could fortuitously hide a genuine memory safety issue whose root cause really does needs addressing.

For this reason we have chosen 0x8123 as a sanitization value – from an operating system perspective this is in the same memory page as the zero address (NULL), but an access violation at 0x8123 will better stand out to the developer as needing more detailed attention.

它不仅解释了 Visual Studio 在指针被删除后如何处理它,还回答了为什么他们选择不自动将其设置为 NULL!


此“功能”作为“SDL 检查”设置的一部分启用。要启用/禁用它,请转到:PROJECT -> Properties -> Configuration Properties -> C/C++ -> General -> SDL checks

确认这一点:

更改此设置并重新运行相同的代码会产生以下输出:

ptr = 007CBC10
ptr = 007CBC10

"feature"用引号引起来,因为在您有两个指向同一位置的指针的情况下,调用 delete 只会清理其中的 ONE。另一个将指向无效的位置...


更新:

在 5 年多的 C++ 编程经验之后,我意识到这整个问题基本上是一个有争议的问题。如果您是 C++ 程序员并且仍在使用 newdelete 来管理原始指针而不是使用智能指针(这可以规避整个问题),您可能需要考虑更改在成为 C 程序员的职业道路上。 ;)

关于c++ - Visual Studio 如何处理已删除的指针,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33374483/

相关文章:

c++ - OS X Lion 上的 libplist 编译错误 : string. h not found

c++ - 具有三元运算符的函数类型

c++ - 多个输入验证约束? C++

c - 使用fgets存储字符指针程序崩溃

C++多态/纯虚函数

delphi - 如何将指向类型的指针视为指向该类型数组的指针

c++ - 使用 const_cast 添加 const-ness - 坏主意?

Git 每次提交和 pull 时都要求输入密码

.net - 无法在 Visual Studio 2012 中打开 .NET 4.0.1 目标项目

嵌套结构的 C 问题(看起来 1 个实例是在没有明确定义的情况下定义的)