【发布时间】:2012-01-06 21:52:15
【问题描述】:
如何在 VS2010 的 STL 实现中关闭“对调试堆的支持”?我写了一个内存跟踪器,它重载了 new 和 delete 并在分配前添加了一个跟踪节点。可悲的是,一些 STL 对象使用我的 operator new,然后尝试使用下面的宏而不是我的 operator delete 来删除。这意味着他们尝试free 一个未被malloc 返回的地址。由于以下宏,我的代码在调试时崩溃,但在发布时没有崩溃(哈哈)。
来自<xdebug>:
// SUPPORT FOR DEBUG HEAP
#if defined(_DEBUG)
#define _DELETE_CRT(ptr) _STD _DebugHeapDelete(ptr)
template<class _Ty>
void __CLRCALL_OR_CDECL _DebugHeapDelete(_Ty *_Ptr)
{ // delete from the debug CRT heap even if operator delete exists
if (_Ptr != 0)
{ // worth deleting
_Ptr->~_Ty();
// delete as _NORMAL_BLOCK, not _CRT_BLOCK, since we might have
// facets allocated by normal new.
free(_Ptr);
}
}
#else /* defined(_DEBUG) */
#define _DELETE_CRT(ptr) delete (ptr)
作为参考,确切的崩溃在locale operator=:
locale& operator=(const locale& _Right) _THROW0()
{ // assign a locale
if (_Ptr != _Right._Ptr)
{ // different implementation, point at new one
_DELETE_CRT(_Ptr->_Decref());
_Ptr = _Right._Ptr;
_Ptr->_Incref();
}
return (*this);
}
我什至看不到 _DebugHeapDelete 购买它们的东西 - 它看起来与 operator delete 在任何配置中所做的相同。
【问题讨论】:
-
如果您在调试和发布模式下通过
delete调用,您可以轻松地回答自己所购买的东西。在调试中,最终将调用_free_dbg_nolock来检查待删除指针(和堆)上的某些内容。在发布模式下,operator delete只会调用free。我不知道他们到底检查了什么以及为什么这样做,但这不是我们现在的事,是吗?我喜欢那个调试堆。 -
@Xeo 但是无论您使用
_DebugHeapDelete还是delete,您都可以获得调试堆的好处。_DebugHeapDelete完全是delete,只是它绕过operator delete并直接调用free。这意味着它绕过了用户的operator delete(即使它被分配给用户的operator new,这对我来说似乎是一个错误)。 那个有什么意义?