65.9K
CodeProject 正在变化。 阅读更多。
Home

具有用户定义转储信息的内存泄漏转储器

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.50/5 (3投票s)

2007年4月11日

2分钟阅读

viewsIcon

27158

downloadIcon

386

如何为内存泄漏添加用户定义的转储信息。

Screenshot - LeaksDumperScreen.gif

引言

CRT调试库提供的内存泄漏信息并不是很有用。 仅显示原始内存快照。 如果开发人员可以以更方便的形式查看对象转储,例如类变量,那就更好了。 这是一个解决方案。它仅适用于 C++ 类。

背景

让我们看一下标准 CRT 调试库提供的内存泄漏转储信息

Detected memory leaks!
Dumping objects ->
e:\net projects\leaksdumperdemo\leaksdumperdemo\common.h(19) : 
    {102} normal block at 0x00359F30, 4 bytes long. Data: <  A > EC 9A 41 00 
Object dump complete.

在这里,我们可以看到转储表示为一系列字节,并且不清楚对象当前的状况。 对于开发人员来说,查看的不是原始数据,而是对象(类)变量的精确值,这可能非常有用。 怎么做呢? 很容易。 CRT 调试库允许您指定用户定义的函数,该函数将转储客户端块。 函数原型是

void DumpClientFunction(void *pUserData, size_t blockSize);

其中

  • pUserData - 指向用户块的指针
  • blockSize - 用户块的大小

要安装一个用户定义的函数来转储 _CLIENT_BLOCK 类型的内存块(仅限调试版本),我们需要调用...

_CrtSetDumpClient(DumpClientFunction);

...在我们的代码中的某个地方。 但是,如何将转储功能添加到用户定义的类型? 想法是从具有一个虚函数 dump_object_info() 的基类派生您的类

class MemoryLeaksDumpBase
{
public:
    virtual void dump_object_info()=0;
};

然后重写此函数并在那里转储您需要的一切。 您可能会问为什么它是一个纯虚函数,只是为了让编译器在您忘记在派生类中重写它时发出警告。

Using the Code

现在让我们看一下如何在您的应用程序中使用代码。 首先,您应该将两个文件 dbg_leaks_dumper.hdbg_leaks_dumper.cpp 包含到您的项目中。 然后从 MemoryLeaksDumpBase 派生您的类,重写 dump_object_info() 函数并转储您想要的任何内容。 请参阅下面带有转储功能的用户定义类型的示例

#include "dbg_leaks_dumper.h"

class UserClass: public dbg::MemoryLeaksDumpBase
{
private:
    void dump_object_info()
    {
        DUMP_OBJECT_INFO("UserClass.Dump()")
    }
};

将这样的初始化代码添加到您的主模块中

INIT_MEMORY_LEAKS_DUMPER(_DUMP_ALL_BLOCKS);

然后对所有用户定义的类型的内存分配使用用户定义的 new 运算符(在我的示例中,它是 _NEW,定义在 common.h 中)。 就这样! 这是我的示例项目中的主模块

// LeaksDumperDemo.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include "UserClass.h"
#include "dbg_leaks_dumper.h"

INIT_MEMORY_LEAKS_DUMPER(_DUMP_ALL_BLOCKS);
//INIT_MEMORY_LEAKS_DUMPER(_USER_BLOCK); // Uncomment this line to dump only
                                         // _USER_BLOCKS

int _tmain(int argc, _TCHAR* argv[])
{
    UserClass* p = _NEW UserClass();

    return 0;
}

现在内存泄漏信息看起来更方便了

Detected memory leaks!
Dumping objects ->
e:\net projects\leaksdumperdemo\leaksdumperdemo\leaksdumperdemo.cpp(13) : 
    {102} client block at 0x00359F30, subtype 2, 4 bytes long.
UserClass.Dump()
Object dump complete.

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.