使用调试版覆盖新版,而不会损坏新版本

时间:2012-10-10 08:38:11

标签: c++ visual-c++ c++03

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而没有引入标题?

5 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:3)

我历史上解决这个问题的方法是使用预编译头文件,并执行类似的操作(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标头,只包含预编译的标头。

答案 2 :(得分:0)

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

我最近编写了一个debug_new调试器,它添加了一个新的关键字&#34; placement&#34;,它会在所有放置新呼叫的前面写入。

您可以在此处查看我的调试器:https://sourceforge.net/projects/debugnew/

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

答案 3 :(得分:0)

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

有更好的选择,比如DUMA,现在有Dr. Memory(与Valgrind类似,但在Windows上),使用DEBUG_NEW憎恶绝对毫无意义。

答案 4 :(得分:-1)

在所有#include行之后,

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