21

可能重复:
C++ 删除 - 它删除了我的对象但我仍然可以访问数据?
可以在其范围之外访问局部变量的内存吗?

我不明白delete当我想释放分配给new. 在 C++ Premiere 书中写道:

这将删除 ps 指针指向的内存;它不会删除指针 ps 本身。例如,您可以重用 ps 来指向另一个新分配。您应该始终平衡使用 new 和使用 delete;否则,您可能会遇到内存泄漏——即,已分配但无法再使用的内存。如果内存泄漏变得太大,它可能会使寻求更多内存的程序停止。

因此,据我所知,delete必须删除 pinter 指向的内存中的值。但事实并非如此。这是我的实验:

int * ipt = new int;   // create new pointer-to-int

cout << ipt << endl;   // 0x200102a0, so pointer ipt points to address 0x200102a0
cout << *ipt << endl;  // 0, so the value at that address for now is 0. Ok, nothing was assigned
*ipt = 1000;     // assign a value to that memory address
cout << *pt << endl;   // read the new value, it is 1000, ok
cout << *((int *) 0x200102a0) << endl;   // read exactly from the address, 1000 too

delete ipt;   // now I do delete and then check
cout << ipt << endl;  // 0x200102a0, so still points to 0x200102a0
cout << *ipt << endl;  // 1000, the value there is the same
cout << *((int *) 0x200102a0) << endl;    // 1000, also 1000 is the value

那么delete真正做什么呢?

4

6 回答 6

61

把内存想象成一个大仓库,里面有很多盒子可以放东西。当您呼叫“新”时,仓库工作人员会找到一个足够大的未使用的盒子以满足您的需求,将该盒子记录为您拥有(因此它不会给其他人),并给您该盒子的编号以便您可以放置你的东西放进去。这个数字将是“指针”。

现在,当您“删除”该指针时,会发生相反的情况:仓库工作人员注意到该特定框再次可用。与真正的仓库工作人员相反,他们没有对盒子做任何事情——所以如果你在“删除”后查看它,你可能会看到你的旧东西。或者你可能会看到其他人的东西,如果盒子在此期间被重新分配。

Technically, you are not allowed to look into your box once you have returned it to the pool, but this is a somewhat weird warehouse with no keys or guards, so you can still do whatever you want. However, it might cause problems with the new owner of the box, so it's expected that you follow the rules.

于 2012-07-22T18:52:54.990 回答
9

undefined behavior只要您取消引用delete语句后的指针,您的实验就有。一切都可能发生,这使您的实验变得毫无价值。

delete(不是delete[])做什么?它释放其参数指向的存储空间。这将触发存储在该位置的对象的析构函数运行。访问已删除的存储会触发未定义的行为(通常是segmentation fault)。不能保证内存实际上被交还给操作系统或其他任何东西。

于 2012-07-22T18:45:46.570 回答
6

delete运算符释放先前使用运算符分配的内存new。这意味着内存现在可供系统使用,例如当new程序稍后有其他用途时。但是,它不会清除内存中的数据。指针仍将指向内存中的相同地址,但访问该块将导致未定义的行为。

最好在ing之后设置一个指向NULL(或nullptr在 C++11 中)的指针。delete任何后续delete的 s 都将是无害的。

于 2012-07-22T18:47:18.753 回答
5

在 -ing之后取消引用指针delete是未定义的行为,因此任何事情都可能发生

通常,delete将内存标记为已释放,以便以后可以重用,但这是一个复杂的话题。

经验法则:永远不要直接使用newand delete(除了实施make_unique,标准由于某种原因缺乏);使用 RAII。

于 2012-07-22T18:47:28.410 回答
5

delete通过 使内存可用于以后的请求new。它是否对内容进行加扰是未定义的。由于将内容保留原样更快,因此在释放模式下,可能会出现内存仍然“可用”。在调试模式下,它可能会被幻数打乱。

您在这里遇到的在 C++ 中称为“未定义行为”。在这种情况下,未定义的行为是由在其生命周期结束后访问一块内存引起的。只是不要这样做。

于 2012-07-22T18:48:29.313 回答
4

delete将内存返回给系统——基本上,它不再为您的程序保留。这并不意味着内存中的值将立即被覆盖,但可能在完成后的任何时间delete。大多数情况下,相同的内存会重新分配给您自己的程序将来使用。

于 2012-07-22T18:48:14.393 回答