5

我正在尝试编写一个小型内存泄漏检测工具。

我的想法是跟踪我的应用程序中的动态内存分配寿命,以确定任何无效的内存访问或未删除的内存,这可能会导致我的应用程序在使用一段时间后变为核心。

我想写一个简单的界面来覆盖newdelete.

在我的重写中,new我想打印功能行地址等。然后调用标准new

有没有人试过这个?我不确定我是否可以从我的班级特定的新运营商那里调用标准新的。

4

4 回答 4

0

::operator new从特定于类的调用operator new很好,而且很常见。您不能从替换版本中调用 global operator new ,::operator new因为如果您替换 global operator new 旧的 operator 不存在。

于 2012-11-15T16:44:16.307 回答
0

在这个问题中,我为您的问题提出了一个临时解决方案:立即检测 Windows 上的堆损坏错误。如何?

通常,您可以使用以下代码替换您的newand :delete

DWORD PageSize = 0;

inline void SetPageSize()
{
    if ( !PageSize )
    {
        SYSTEM_INFO sysInfo;
        GetSystemInfo(&sysInfo);
        PageSize = sysInfo.dwPageSize;
    }
}

void* operator new (size_t nSize)
{
    SetPageSize();
    size_t Extra = nSize % PageSize;
    nSize = nSize + ( PageSize - Extra );
    return Ptr = VirtualAlloc( 0, nSize, MEM_COMMIT, PAGE_READWRITE);
}

void operator delete (void* pPtr)
{
    MEMORY_BASIC_INFORMATION mbi;
    VirtualQuery(pPtr, &mbi, sizeof(mbi));
    // leave pages in reserved state, but free the physical memory
    VirtualFree(pPtr, 0, MEM_DECOMMIT);
    DWORD OldProtect;
    // protect the address space, so noone can access those pages
    VirtualProtect(pPtr, mbi.RegionSize, PAGE_NOACCESS, &OldProtect);
}

确定内存的无效访问。在进一步的讨论中,您将找到有关泄漏检测和其他内存错误检测的想法。

如果要调用全局newand delete,可以使用::全局命名空间前缀:

return ::new(nSize);
于 2012-11-15T16:45:11.933 回答
0

所描述的方法听起来很合理。您可以增强它并将每个分配上的一些标识数据存储到某个数据结构中。这样,您可以在程序终止时跟踪所有未释放的内存,而无需检查所有分配/释放日志。

为了检测损坏,您可以在开始之前和结束之后用填充包装每个分配,并用一些预定义的模式填充它。释放内存后,您可以验证模式是否仍然存在。这将使您有很好的机会检测腐败。

new您可以使用范围前缀调用全局: ::new

于 2012-11-15T16:49:59.533 回答