Visual Studio对删除的指针做了什么?为什么? 我曾经读过的一个C++书籍,指出当使用“代码>删除”/代码>运算符删除指针时,指向它的位置的内存“释放”,并且可以被重写。它还表示指针将继续指向同一位置,直到重新分配或设置为NULL
然而,在VisualStudio2012中;事实似乎并非如此 示例: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
#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>和
/sdl
编译选项的副作用。对于VS2015项目,默认情况下启用该选项,可启用/gs提供的安全检查之外的其他安全检查。使用项目>属性>C/C++>常规>SDL检查设置来更改它
引述:
- 执行有限的指针清理。在不涉及解引用的表达式和没有用户定义析构函数的类型中,指针引用在调用delete后被设置为无效地址。这有助于防止重复使用过时的指针引用
delete ptr;
delete ptr;
cout << "ptr = " << ptr << endl;
cout删除指针后,指针指向的内存可能仍然有效。要显示此错误,请将指针值设置为一个明显的值。这确实有助于调试过程。如果该值被设置为NULL
,它可能永远不会在程序流中显示为潜在的bug。s