string *str=new string;
delete str;
删除对象后,str指针自身占用的空间是否存在?
是的当然。str
类型的变量string *
仍在范围内。一旦退出当前范围,它将不复存在。例如,在{ }
包含这些指令的函数或 - 分隔块的末尾。
这就是为什么最好停止指向new string
曾经分配过的地址,现在它不再有效。现有的指向有效内存或 NULL 总是好的。
string *str = new string;
delete str;
str = NULL;
请注意,在第三行之后,您现在可以询问“str 是否指向有效的内存位置?”,即“我可以安全地取消引用它吗?”。
if (str != NULL) ...
另一方面,如果不将指针设置为 NULL,则不可能进行这种检查。您应该记住,在删除指令之后,现在取消引用 str 是无效的,因此不要这样做。显然这是在自找麻烦。
虽然是正确的,但这种代码(一个新的本地匹配删除,以及在删除其目标内存位置后设置为 NULL 的任何活动指针)非常容易受到攻击,并且在将来发生更改时容易出错。例如,如果函数不是那么简单,并且在 new 和 delete 之间的路径中有条件和循环怎么办?如果您将 str 作为参数传递给另一个函数怎么办?这个函数对指针做了什么:复制它,克隆它指向的对象......?
一种称为RAII - Resource Allocation Is Initialization的技术(请参阅此问题)有助于创建可防止内存泄漏和内存访问违规等错误的设计。
注意:稍微更直观一些,尽管此站点上建议的 RAII 名称不那么正统:UDSTMR - 使用析构函数语义来管理资源,或 UTSTTC - 使用堆栈触发清理。看到这个答案。
C++ 的删除操作符做了两件事:
通常,类在内存中保存的数据会保留一段时间,但几乎可以肯定的是,在某个时刻有人会覆盖它们,因此不应依赖它们的存在和凝聚力。
存储在str
变量中的指针被保留并仍然指向该部分内存。string
您可以通过再次调用运算符重用此指针并分配另一个new
。
奇怪的是,旧的 DOS 游戏 SimCity 有一个错误,导致释放后使用释放的内存。由于这款游戏非常受欢迎,Windows 设计师为此游戏准备了一个特定规则,允许它安全地使用释放的内存,这样它就可以在 Windows 中运行。
后
delete str
str
还存在。这行代码释放了所str
指向的内存,所以你可以new
再次使用它。
int main()
{
string *str=new string;
delete str;
}
这是做什么的,
创建一个名为的容器str
,它能够指向一个字符串。现在,当你这样做时delete str
,实际的字符串会被删除。但是指针仍然可以指向那个内存位置。(尽管您可能不被允许访问它)。这个指针的范围是直到你}
完成main
后将被销毁(分配的内存在堆栈上释放)main