我正在为c ++制作内存泄漏检测器。它取代了全局new运算符,并使用宏来初始化两个全局变量__file__
和__line__
,如下所示:
#define new (__file__=__FILE__,__line__=__LINE__) && 0 ? NULL : new
我从另一个名字我记不起来的StackOverflow用户那里学到了这个技巧。这适用于涉及new的简单操作,但是当用户为命名空间定义新的本地运算符时,此appraoch会导致问题。一方面,像
这样的行void* operator new(size_t size);
也与宏匹配;同样,显式调用全局new,例如:
int* i = ::new int;
导致句法错误。
有没有办法在部分代码中重新定义或禁止__LINE__
和__FILE__
常量(以便它们显示对operator new的调用的文件名和行号)?如果没有,如何改进宏以不匹配用户定义的“operator new”并且不会导致“:: new”出现问题?
我真的很想摆脱宏的困境。在此先感谢:)
答案 0 :(得分:0)
我知道没有办法这样做非侵入性的。在过去,我使用了正则表达式或c ++函数替换工具(如Visual Studio中提供的重构工具)来更改new
的所有实例,以显式调用记录文件和行号的宏。
另一种选择是检测内存系统以记录堆栈帧。此方法具有较高的运行时成本,但如果由于滥用经常使用的库代码而发生的分配发生泄漏,则偶尔会有用。没有平台无关的方法可以执行此操作,请参阅this问题以获取适用于常见平台(Linux和Windows)的信息。
编辑:对于您的具体情况,您可以取消定义宏,并在导致问题的new
标识符实例后重新定义它。
答案 1 :(得分:0)
好的,我已经放弃了尝试让宏工作。从它的外观来看,它不可能。我写了一个perl脚本来完成这项工作。它在预处理(预处理器)之前运行,并且它比C预处理器做的更聪明。 这些是用于将new和:: new匹配到其他内容的正则表达式:
$this =~ s/(::)?\s*new([^\w_])/__fl_init(__FILE__,__LINE__)?NULL: $1new$2/g;
我不知道,也许我会写一个批处理文件来自动预处理源代码。如果有人知道使用CPP的解决方法,请发表评论。