我想重载全局和非全局的新/删除操作符以进行日志记录。
由于我只想添加日志信息,我想保留此运算符的标准行为。
有没有办法重载new / delete操作符来添加日志记录,但不必重写标准行为(可能容易出错)?
实际上,我不仅需要标准行为。我需要与Visual 2010实现相同的行为,这可能不是标准的。
我正在寻找的这种日志记录的错误是新的[] /删除不匹配。
我可以使用经典工具,但它们会减慢执行速度,我想与其他人共享二进制文件以收集更多信息。
答案 0 :(得分:4)
您可以使用malloc
/ free
进行基本分配。处理完整
new
的标准合规性有点棘手;你需要这样的东西:
void*
operator new( size_t n )
{
void* results = malloc( n );
while ( results == NULL ) {
if ( std::get_new_handler() == NULL ) {
throw std::bad_alloc();
}
(*std::get_new_handler())();
results = malloc( n );
}
return results;
}
但是,您通常不需要完全合规。如果你这么说的话
您不支持设置new_handler
,例如,您可以
大大简化。在我用于测试的重载版本中,事实上,
如果malloc
确实失败了,我就会中止(但这个版本有选项可以
因为我想测试我的代码,所以根据需要触发new
的失败
也正确地对它做出反应。)
如果您正在登录,请务必小心避免无休止的递归。唯一的
保证函数不在标准库中使用operator new
是malloc
和free
。当然,很多人没有理由分配
动态地,我不担心像memcpy
或...这样的函数
strlen
。在实践中,您可能对任何功能都很安全
在C库中(虽然理论上可以实现printf
)
iostream
)的条款。但任何使用iostream,locale或标准
容器已经用完,除非你防止递归:
void*
operator new( size_t n )
{
static int recursionCount = 0;
++ recursionCount;
void* results = malloc() ;
// Any additional logic you need...
if ( recursionCount == 1 ) {
logAllocation( results, n );
}
-- recursionCount;
return results;
}
正式地,你应该为operator delete
做同样的事情,尽管在。{
练习,如果你要登录一个文件,我不指望任何delete
除了close()
或析构函数。
答案 1 :(得分:0)
您可以重新定义new
关键字以调用其他签名并传递__FILE__
等。
在一般情况下,这可以解决问题。当你开始使用覆盖operator new
的对象时,虽然你有点搞砸了。
如果我通过记忆知道它我会分享,但你可以找到谷歌。我认为在某个地方的codeproject上有一个实现。