Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual Studio对删除的指针做了什么?为什么? 我曾经读过的一个C++书籍,指出当使用“代码>删除”/代码>运算符删除指针时,指向它的位置的内存“释放”,并且可以被重写。它还表示指针将继续指向同一位置,直到重新分配或设置为NULL_C++_Pointers_Visual Studio 2012_Memory Management_Delete Operator - Fatal编程技术网

Visual Studio对删除的指针做了什么?为什么? 我曾经读过的一个C++书籍,指出当使用“代码>删除”/代码>运算符删除指针时,指向它的位置的内存“释放”,并且可以被重写。它还表示指针将继续指向同一位置,直到重新分配或设置为NULL

Visual Studio对删除的指针做了什么?为什么? 我曾经读过的一个C++书籍,指出当使用“代码>删除”/代码>运算符删除指针时,指向它的位置的内存“释放”,并且可以被重写。它还表示指针将继续指向同一位置,直到重新分配或设置为NULL,c++,pointers,visual-studio-2012,memory-management,delete-operator,C++,Pointers,Visual Studio 2012,Memory Management,Delete Operator,然而,在VisualStudio2012中;事实似乎并非如此 示例: #include <iostream> using namespace std; int main() { int* ptr = new int; cout << "ptr = " << ptr << endl; delete ptr; cout << "ptr = " << pt

然而,在VisualStudio2012中;事实似乎并非如此

示例:

#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;
}

显然,当调用delete时,指针指向的地址会发生变化

为什么会这样?这是否与VisualStudio有关


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

我相信,您正在运行某种调试模式,而VS正试图将指针重新指向某个已知位置,因此,可以追踪并报告进一步试图取消引用的情况。尝试在发布模式下编译/运行相同的程序

为了提高效率和避免给出错误的安全概念,指针通常不会在
delete
中更改。在大多数复杂的场景中,将delete pointer设置为预定义的值是没有用的,因为被删除的指针可能只是指向该位置的几个指针中的一个

事实上,我想得越多,我就越发现VS像往常一样在这样做的时候有错。如果指针是常量呢?它还能改变它吗

它还声明指针将继续指向同一位置,直到重新分配或设置为NULL为止

这绝对是误导性的信息

显然,当调用delete时,指针指向的地址会发生变化

为什么会这样?这是否与VisualStudio有关

这显然在语言规范中<调用
delete
后,code>ptr无效。在
delete
d之后使用
ptr
是未定义行为的原因不要这样做。调用
delete
后,运行时环境可以自由地使用
ptr
执行任何它想做的事情

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


将指针的值更改为任何旧值在语言规范范围内。至于将其更改为NULL,我会说,那将是不好的。如果指针的值设置为NULL,程序将以更理智的方式运行。然而,这将隐藏问题。当程序使用不同的优化设置编译或移植到不同的环境时,问题可能会在最不合适的时候出现。

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

这似乎很奇怪,所以我做了一点挖掘,发现这里面包含了一个章节,讨论“删除C++对象时自动指针的消毒”。 …NULL检查是一种常见的代码构造,这意味着现有的NULL检查与使用NULL作为清理值相结合,可能会意外地隐藏真正的内存安全问题,其根本原因确实需要解决


出于这个原因,我们选择0x8123作为清理值–从操作系统的角度来看,这与零地址(NULL)在同一内存页中,但0x8123处的访问冲突对于开发人员来说更为突出,因为需要更详细的注意

它不仅解释了VisualStudio在删除指针后对指针所做的操作,还回答了为什么他们选择不自动将指针设置为
NULL


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

要确认这一点:

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

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

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


更新:
5年后的C++编程经验,我意识到整个问题基本上是个未知数。如果你是一个C++程序员,仍然使用<代码>新< /COD>和删除>代码>来管理原始指针,而不是使用智能指针(这绕过整个问题),你可能想考虑职业路径的改变,成为C程序员。p> 您可以看到
/sdl
编译选项的副作用。对于VS2015项目,默认情况下启用该选项,可启用/gs提供的安全检查之外的其他安全检查。使用项目>属性>C/C++>常规>SDL检查设置来更改它

引述:

  • 执行有限的指针清理。在不涉及解引用的表达式和没有用户定义析构函数的类型中,指针引用在调用delete后被设置为无效地址。这有助于防止重复使用过时的指针引用
请记住,在使用MSVC时,将已删除的指针设置为NULL是一种不好的做法。它破坏了您从调试堆和此/sdl选项获得的帮助,您无法再检测程序中的无效空闲/删除调用。

delete ptr;
delete ptr;
cout << "ptr = " << ptr << endl;

cout删除指针后,指针指向的内存可能仍然有效。要显示此错误,请将指针值设置为一个明显的值。这确实有助于调试过程。如果该值被设置为
NULL
,它可能永远不会在程序流中显示为潜在的bug。s