8

我有一个庞大的应用程序(几百万个 LOC,和数万个文件),我正在尝试使用调试 crt 来检测内存泄漏。我正在尝试像这样对 new 进行宏化:

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#ifndef NEW_DEBUG
#define NEW_DEBUG new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new NEW_DEBUG
#endif

现在,我的应用程序太大了,所以对我来说,理想情况下,我会将它放在一个头文件中,并专门将它包含在数以万计的 CPP 文件中。不是一个有趣的任务。所以我试图将它放在我们 SDK 中的一个通用头文件中,该头文件将包含在每个翻译单元中。

我遇到的问题是它似乎与一些 STL 头文件发生冲突,并且在使用放置 new 时编译器会发出错误。我可以在自己的代码中更改它,方法是使用编译指示并禁用新宏。那里没有问题。使用placement new的是STL头文件,我无法更改。

通过重新排列 cpp 文件中的 include 指令,我找到了一种解决方法。例如:

// doesn't compile
#include "new_redirect.h"
#include <map> // for instance

// does compile
#include <map> // for instance
#include "new_redirect.h"

但这是一个困难的解决方法,因为我必须再次修改数千个文件,并确保首先包含它们的 STL 标。具有讽刺意味的是,我创建了一个 hello world 应用程序来专门测试这个问题:而且我的 hello-world 应用程序编译得很好。但是,如果没有这种解决方法,我的大型应用程序就不会。

所以我的问题是:

  1. 有没有人能够在不抖动大量代码的情况下完全宏化新的?(以相对无痛的方式)
  2. 有没有其他方法可以重新安排我的 STL 标头包含指令?

谢谢

4

1 回答 1

4

您可以使用可变参数宏捕获新的展示位置:


#define NEW_DEBUG(...) NEW_DEBUG2(_NORMAL_BLOCK, __FILE__, __LINE__, __VA_ARGS__ )
#define new NEW_DEBUG

但是预处理器似乎不允许定义带参数和不带参数的宏,并且首先应用不带参数的宏,所以我没有找到一种方法来通过单个预处理器传递来做到这一点。但是似乎有两个可能,如果我们使用上面的宏和 /E 运行第一遍,然后使用第二遍


#define NEW_DEBUG new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define NEW_DEBUG2(...) new(__VA_ARGS__ )
于 2011-02-14T16:04:56.557 回答