C ++是删除操作符重写内存吗?

时间:2016-10-15 08:02:42

标签: c++ memory

我正在使用MVS 2010 C++处理项目。编译选项是默认的。我认为运算符delete没有重写内存,只标记堆中空闲的内存。我做了一个测试项目,其中一个字符串由new运算符动态创建,并由delete运算符释放。我检查了内存窗口中的内存,并在delete内存被覆盖之后。它也在发布时发生。在发布模式(没有调试)中,我创建了一个进程转储,并在记事本中搜索字符串。我找到了字符串。然后我在delete之后创建了一个转储,并在转储文件中搜索了该字符串。字符串不存在。

我的问题是为什么delete即使在发布模式下也会覆盖字符串?

3 个答案:

答案 0 :(得分:1)

在许多流行的堆管理实现中,“标记堆中空闲的内存”通常需要重写至少部分内存。这就是“标记为免费”的方式。

通常,现在空闲内存块的某些部分实际上由堆管理器用于内部目的(维护空闲阻止列表等)。这种重新用途和随后的重写很可能是您在案例中观察到的。

通常,它是空闲块的开头,可以重用于内部用途。在一些实现中,它可能是开始和结束。因此,如果你分配一个足够长的字符串,你至少应该能够看到该字符串的中心部分在释放的内存块中保持完整。

不要让它太长,因为堆管理器可能决定直接从操作系统请求大内存块,并在释放后将它们返回给操作系统。这是一个完全不同的故事。

答案 1 :(得分:0)

使用旧的C,您可以释放一个块,它将保持有效,直到下一次调用malloc()。但这已经很久没有了。应用程序经常“粉碎”内存,部分是为了协助调试,但也作为一种安全措施,以防止其他代码查看垃圾,可能是为了记录密码或其他敏感信息。此外,内存可能已经被提供给另一个进程。

答案 2 :(得分:0)

一旦你调用了删除,内存管理器可以自由地对内存做任何想做的事情。可能会发生任何事情,包括:

  1. 可以覆盖以进行调试
  2. 将块添加到空闲内存池
  3. 合并已释放的块。
  4. 该块被重新分配并写入其他地方(例如,在库函数中)。
  5. 您希望在删除时不会覆盖您的数据,这是不切实际的。