问题描述
我无法入睡! :)
我在Windows上一个相当大的项目,并遇到了一些堆损坏问题。我已阅读全部SO,包括这个漂亮的话题:,但没有什么是合适的,帮我盒子外面。 调试CRT
和的BoundsChecker
检测堆损坏,但地址总是不同的检测点总是远离实际内存覆盖。我还没有睡,直到深夜,并制作了下面的技巧:
DWORD每页= 0;内嵌无效SetPageSize()
{
如果(!每页)
{
SYSTEM_INFO SYSINFO;
的GetSystemInfo(安培; SYSINFO);
每页= sysInfo.dwPageSize;
}
}void *的new操作符(为size_t n大小)
{
SetPageSize();
为size_t额外= n大小%每页;
n大小= n大小+(每页 - 额外的);
返回PTR = VirtualAlloc的(0,n大小,MEM_COMMIT,PAGE_READWRITE);
}无效的operator delete(void *的PPTR)
{
MEMORY_BASIC_INFORMATION MBI;
VirtualQuery来(PPTR,&安培; MBI,sizeof的(MBI));
//休假页,保留状态,但免费物理内存
VirtualFree(PPTR,0,MEM_DECOMMIT);
DWORD OldProtect;
//保护的地址空间,因此没有人可以访问这些页面
VirtualProtect的(PPTR,mbi.RegionSize,PAGE_NOACCESS,&安培; OldProtect);
}
有些堆损坏错误变得明显,我能够解决这些问题。有退出没有更多的调试CRT警告。但是,我有一个关于这个技巧的一些问题:
1 它可以产生任何误报?
2 它会错过一些堆损坏的? (即使我们更换的malloc / realloc的/免费的吗?)
3。它未能与 OUT_OF_MEMORY
在32位模式运行,仅在64位。我是不是正确的,我们只是在32位用完虚拟地址空间?
So, this will only catch bugs of the class "use after free()". For that purpose, I think, it's reasonably good.
If you try to delete
something that wasn't new
'ed, that's a different type of bug. In delete
you should first check if the memory has been indeed allocated. You shouldn't be blindly freeing the memory and marking it as inaccessible. I'd try to avoid that and report (by, say, doing a debug break) when there's an attempt to delete
something that shouldn't be deleted because it was never new
'ed.
Obviously, this won't catch all corruptions of heap data between new
and and the respective delete
. It will only catch those attempted after delete
.
E.g.:
myObj* = new MyObj(1,2,3);
// corruption of *myObj happens here and may go unnoticed
delete myObj;
Typically you have available about ~2GB of the virtual address space on a 32-bit Windows. That's good for at most ~524288 new
's like in the provided code. But with objects bigger than 4KB, you'll be able to successfully allocate fewer instances than that. And then address space fragmentation will reduce that number further.
It's a perfectly expected outcome if you create many object instances during the life cycle of your program.
这篇关于即时检测在Windows堆损坏的错误。怎么样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!