【问题标题】:replacing new with macro conflicts with placement new用宏替换 new 与放置 new 冲突
【发布时间】:2011-06-26 19:51:36
【问题描述】:

我有一个庞大的应用程序(数百万个 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 文件中重新排列包含指令。例如:

// 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 标头包含指令吗?

谢谢

【问题讨论】:

标签: c++ windows memory-leaks crtdbg.h


【解决方案1】:

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


#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__ )

【讨论】:

  • 感谢您的出色回答。我想我们只能希望编译器能够执行两次传递……等等,我想要一种不使用一次传递的编程语言。啊,真是一团糟。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
  • 2016-08-18
  • 1970-01-01
  • 1970-01-01
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多