8

Microsoft 运行时库提供调试版本的分配函数。对于 C++,这是带有签名的 operator new 的调试变体:

void *operator new(size_t size, int blockType, const char *filename, int linenumber);

并且宏定义为

#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)

现在要检测所有分配,通常定义

#if defined DEBUG_NEW
#define new DEBUG_NEW
#endif

然而这个定义打破了任何使用placement new的地方,因为这两组参数最终是语法错误。现在我可以轻松处理我们代码中的少数用途,但标准库和 boost 使用新的布局。因此,全局定义它意味着在定义之前包含很多东西,这会减慢编译速度。

那么是否有任何方法可以在我们的代码中检测分配而无需仅仅因为它们包含新的位置而无需将上面的最后一个定义放在所有文件中或手动编写 DEBUG_NEW 吗?

4

5 回答 5

7
#pragma push_macro("new")
#undef new

new(pointer) my_class_t(arg1, arg2);

#pragma pop_macro("new")

或者

#pragma push_macro("new")
#undef new

#include <...>
#include <...>
#include <...>

#pragma pop_macro("new")
于 2014-02-07T15:02:58.327 回答
4

我过去解决这个问题的方法是使用预编译的头文件,并执行类似的操作(StdAfx.h、Pch.h、PreCompiled.h 或其他):

//First include all headers using placement new
#include <boost/tuple/tuple.hpp>
#include <vector>

#define new MY_NEW
#define MY_NEW new(__FILE__, __LINE__)   

然后确保没有文件直接包含 boost 标头,而只有预编译的标头。

于 2012-10-10T08:48:56.540 回答
0

我知道这有点晚了,但是可以通过使用模板魔术来解决这个问题。

我最近一直在编写一个 debug_new 调试器,它添加了一个新的关键字“placement”,它被写入所有放置新调用的前面。

你可以在这里查看我的调试器:https ://sourceforge.net/projects/debugnew/

或者来自 nvwa 的 debug_new 调试器:https ://sourceforge.net/projects/nvwa/

于 2015-02-04T13:04:44.087 回答
0

这整个 DEBUG_NEW 东西应该在火中死去!它只是几乎没有用,而且在现代 C++ 中根本没有用,因为你不再new在理智的 C++ 中看到它。

有更好的选择,比如 DUMA,现在有了Dr. Memory (它的工作原理与Valgrind类似,但在 Windows 上),使用 DEBUG_NEW 可憎绝对没有意义。

于 2017-11-02T21:04:56.893 回答
-1

define new DEBUG_NEW在所有#include 行之后,行应该放在源文件中。通过这种方式,它仅适用于您自己的代码,而不适用于任何其他 h 文件,如 Boost。全局新的 DEBUG_NEW 重新定义可能会导致编译失败,应该避免。

于 2012-10-10T08:54:24.860 回答