在delete
之后,您不应该使用指针。我的下面的示例访问a
是基于实现定义的行为。(感谢M.M和Mankarse指出这一点)
我认为这里重要的不是变量a
(或b
、c
、d
),而是值(=已释放块的内存地址),在某些实现中,当在某些“指针上下文”中使用时,可能会触发运行时错误。
这个值可能是一个rvalue/表达式,不一定是存储在变量中的值——所以我不相信a
的值会改变(我使用宽松的“指针上下文”来区分与在非指针相关表达式中使用相同的值,即相同的一组位,这不会导致运行时错误)。
------------我的原始帖子如下。---------------
好吧,你的实验已经接近完成了。只需添加一些cout
,就像这样:
class A {};
A* a = new A();
A* b = a;
std::cout << a << std::endl;
delete a;
std::cout << a << std::endl;
A* c = a;
A* d = b;
调用delete a
对变量a
不会产生任何影响。这只是一个库调用。管理动态内存分配的库会保留已分配内存块的列表,并使用变量a
传递的值将其中一个先前分配的块标记为已释放。
虽然Mankarse从C++文档中引用的内容是正确的,即:"使所有指向已释放存储区域的指针无效" - 请注意,变量a
的值仍然保持不变(您没有通过引用而是通过值传递它!)。
因此,总结并尝试回答您的问题:
a
变量在delete
后仍存在于作用域中。变量a
仍然包含相同的值,即为class A
对象分配的内存块的起始地址(现在已释放)。
这个a
的值在技术上可以被使用-例如可以像上面的例子一样打印它,但是很难找到比打印/记录过去更合理的用途…
您不应该尝试解引用此值(您也保留在变量b
、c
和d
中的值),因为此值不再是有效的内存指针。
您永远不应该依赖于对象在已释放的存储中(虽然C++不要求在使用后清除已释放的存储),因为您没有任何保证和安全的检查方式。
d=b
是合法的,而b
持有与a
完全相同的值却是非法的? - Sergey KalinichenkoA* c = a;
是合法的 - 只是有点愚蠢。 - Richard Crittendelete
修改指针本身,因此产生了这些想法。 - Slava