当前位置:  开发笔记 > 编程语言 > 正文

宏替换C++运算符new

如何解决《宏替换C++运算符new》经验,为你挑选了2个好方法。

是否有可能创建宏来替换operator new包含额外args的所有形式的重载...说__FILE____LINE__

麻烦似乎operator new可以用括号括或不用括号编码,因此:

类似对象的宏:

#define new new(__FILE__, __LINE__)

将取代声明,如:

A* a = new A();

类似函数的宏:

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

将取代声明,如:

A* a = new(std::nothrow) A();

不幸的是,尝试使用相同的标识符声明两个宏是错误的,即使它们的类型不同,因此以下操作失败:

#define new new(__FILE__, __LINE__)
#define new(A) new (A, __FILE__, __LINE__) // Error: "new" already defined

由于我正在使用g ++,我希望使用它们的可变参数宏的语法会产生成功,但遗憾的是没有.下列:

#define new(...) new(__FILE__, __LINE__, ## __VA_ARGS__)

只匹配new(xyx) A(),而不是new A().

我知道有些文章是关于为什么不可能写的,但我觉得我很亲密,必须有办法.我有什么明显的遗失吗?



1> 小智..:

这是我使用的:

在new.cpp

const char* __file__ = "unknown";
size_t __line__ = 0;

void* operator new(size_t size) {
    void *ptr = malloc(size);
    record_alloc(ptr,__file__,__line__);
    __file__ = "unknown";
    __line__ = 0;
    return ptr;
}

void delete(void *ptr)
{
   unrecord_alloc(ptr);
   free(ptr);
}

为了紧凑,我省略了new和delete的其他定义."record_alloc"和"unrecord_alloc"是维护包含ptr,line和file的结构的链表的函数.

在new.hpp中

extern const char* __file__;
extern size_t __line__;
#define new (__file__=__FILE__,__line__=__LINE__) && 0 ? NULL : new

对于g ++,"new"只扩展一次.关键是"&& 0",它使其成为假并导致使用真正的新内容.例如,

char *str = new char[100];

由预处理器扩展到

char *str = (__file__="somefile.c",__line__=some_number) && 0 ? NULL : new char [100];

因此,记录文件和行号,并调用您的自定义新函数.

这适用于任何形式的新 - 只要new.cpp中有相应的表单


我认为使用逗号运算符会导致代码出现问题:`f(new char [100]);`它中的逗号会使它们成为两个参数.但是,做`(__ file __ = __ FILE __,__ line __ = __ LINE __,0)?0:新的`可能会更好.避免不必要的`&&`操作,并避免包括``
难道你不能使用逗号运算符而不是&& 0?NULL :? 比如,`#define new(file = ..,line = ..),new`,就像@dirkgently建议用他的答案?
我喜欢这个调试版本的解决方案.它不是线程安全的,但是一些线程本地存储修复了它.我认为这会使发布版本的成本有点高......但是版本构建中从来没有任何泄漏

2> JaredPar..:

你应该看看我的同事凯文的这篇优秀博客文章.我们最近有一种情况,我们想要启用这种类型的修复,以便将内存泄漏与在诊断/调试版本中分配它们的行相关联.这是一个有趣的技巧

http://blogs.msdn.com/calvin_hsia/archive/2009/01/19/9341632.aspx


该技术实际上并不显示新调用的文件/行.当__FILE__和__LINE__作为默认函数参数传递时,您始终会获得声明函数的文件/行.即使他的样本输出显示了这一点
推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有