重新定义_行_和_文件_u常量 我正在制作一个C++内存泄漏检测器。它将替换全局新运算符,并使用宏初始化两个全局变量,\uuuuuuuuuuuuuuuu文件和\uuuuuuuuu行,如下所示: #define new (__file__=__FILE__,__line__=__LINE__) && 0 ? NULL : new

重新定义_行_和_文件_u常量 我正在制作一个C++内存泄漏检测器。它将替换全局新运算符,并使用宏初始化两个全局变量,\uuuuuuuuuuuuuuuu文件和\uuuuuuuuu行,如下所示: #define new (__file__=__FILE__,__line__=__LINE__) && 0 ? NULL : new,c++,gcc,macros,C++,Gcc,Macros,我从另一个StackOverflow用户那里学到了这个技巧,我记不起他的名字了。这适用于涉及new的简单操作,但是当用户为名称空间定义新的本地运算符时,此方法会导致问题。一方面,像 void* operator new(size_t size); 也与宏匹配;此外,还可以显式调用global new,例如: int* i = ::new int; 导致语法错误 是否有办法在部分代码中重新定义或抑制\uuuuu LINE\uuuuuuu和\uuuu FILE\uuuuuuuuu常量(以便它们显

我从另一个StackOverflow用户那里学到了这个技巧,我记不起他的名字了。这适用于涉及new的简单操作,但是当用户为名称空间定义新的本地运算符时,此方法会导致问题。一方面,像

void* operator new(size_t size);
也与宏匹配;此外,还可以显式调用global new,例如:

int* i = ::new int;
导致语法错误

是否有办法在部分代码中重新定义或抑制
\uuuuu LINE\uuuuuuu
\uuuu FILE\uuuuuuuuu
常量(以便它们显示调用运算符new的文件名和行号)?如果不是,如何改进宏,使其不匹配用户定义的“操作员新建”,并且不会导致以下问题:“新建”


我真的很想摆脱宏的神奇。提前感谢:)

我知道没有什么方法可以不引起注意地做这件事。在过去,我使用了ReGEX或C++函数替换工具(如VisualStudio中的重构工具)来更改<代码>新< /Cord>的所有实例,以显式调用记录文件和行数的宏。 另一个选择是对内存系统进行检测,以记录堆栈帧。这种方法会带来更高的运行时成本,但如果泄漏是由于频繁使用的库代码的误用而导致的分配而发生的,则这种方法偶尔会有用。没有平台无关的方法可以做到这一点,有关适用于通用平台(linux和windows)的信息,请参阅问题


编辑:对于您的特定情况,您可以取消定义宏,并在出现问题的
新的
标识符实例后重新定义它。

好的,我已经放弃了使宏工作的尝试。从表面上看,它不能。我已经编写了一个perl脚本来完成这项工作。它在预处理(预预处理器)之前运行,并且它比C预处理器做得更聪明。 以下是用于将new和::new匹配到其他内容的正则表达式:

$this =~ s/(::)?\s*new([^\w_])/__fl_init(__FILE__,__LINE__)?NULL: $1new$2/g;

我不知道,也许我会写一个批处理文件来自动预处理源代码。如果有人知道如何使用CPP,请发表评论。

太糟糕了,我正在为一个既没有windows也没有linux库的平台开发此应用程序。此外,我需要跟踪对全局新的调用,因此忽略这些行可能是不可行的。这就是C++语言定义不允许创建重新定义关键字的宏的原因。但是,重新定义关键字并不能成为泄漏检测器(除非您假定它始终是泄漏的最后一个分配)。虽然您已经在使用非标准的东西,但我还是建议您使用一个自定义分配器来重载全局
运算符new
delete
,该分配器可以记住每个分配的
\u内置返回地址(1)
。@Damon宏不是程序的唯一部分,我确实替换了全局new和delete运算符。这些信息被存储在一个链表中。很高兴听到你放弃了这一努力,因为创建宏定义语言关键词应该是犯罪行为,这是因为C++标准禁止它。