在Windows上,我注意到尝试取消引用指向最近释放的内存的指针会导致崩溃,由Visual Studio捕获,说明内存无效。这是预期的。但是,执行相同的应用程序和代码路径导致取消引用指向最近释放的内存的指针不会立即导致Linux崩溃。这告诉我,即使在调试版本中,Linux内核(或GNU C ++运行时)也不会非常快速地使释放的内存失效。应用程序崩溃需要更长的时间。是这样的吗?如果是这样,我可以强制内存更快地取消映射吗?如果不是那么发生了什么?
答案 0 :(得分:2)
你试过http://valgrind.org/吗?它的目的是帮助追踪您所描述的问题。
答案 1 :(得分:2)
new
/ delete
的大多数实现都不返回内存
立即到系统,或至少不返回较小
块。你的代码崩溃了,我感到很惊讶
Windows只需取消引用指向内存的指针;你是
确定你没有做更多的事情(例如使用你读的值
通过指针)。
块有多大?许多实现使用不同的
策略取决于块的大小,并将免费
非常大的块立即。 (IIRC,Linux会做mmap
立即为非常大的块,并立即取消映射
你释放它。当然,如果你之间重新分配内存
免费和解除引用指针,它可能是
address在新分配的空间中,不会崩溃。)
最后:映射的粒度是页面,而你
不能指望分配器阻塞每个分页器的完整页面
分配,只是为了使内存无效
立即解除分配。 (一页可能至少是4K,
并且您不希望每次都丢失4K地址空间
分配16个字节。)没有跟踪所有内存访问(如
ValGrand或Purify),运行速度慢很多,唯一
另一种方法是使用垃圾收集,以确保
只要有指向它的指针,就不会重新分配内存,
并在解除分配时完全覆盖它(即delete
或free
)具有可能导致问题的值(如果使用)
(0xDEADBEEF
,或类似的东西)。即便如此,你也是
并没有真正保证你会崩溃 - 0xDEADBEEF
可以
对于您认为正在阅读的内容,这是一个有效的价值。 (但是这个
允许例如在构造函数中设置一个标志,重置它
在析构函数中,并在每个函数中测试它。对于代码
必须积极防守。)