我想重载全局和非全局 new/delete 运算符以进行日志记录。
由于我只想添加日志信息,因此我想保留此运算符的标准行为。
有没有办法重载 new/delete 运算符来添加日志记录,但不必重写标准行为(这可能容易出错)?
其实,我需要的不仅仅是规范的行为。我需要与 Visual 2010 实现相同的行为,这可能不是标准的。
我在这种日志记录中寻找的错误类型是 new[]/delete 不匹配。
我可以使用经典工具,但它们会减慢执行速度,我想与其他人共享二进制文件以收集更多信息。
最佳答案
您可以使用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
失败,因为我想测试我的代码
也能正确 react )。
如果您正在记录日志,请非常小心,避免无休止的递归。唯一的
保证函数不使用标准库中的operator new
是malloc
和free
。当然,很多都没有理由分配
动态地,我不担心像 memcpy
或
strlen
。实际上,您可能可以安全地使用任何功能
在 C 库中(尽管理论上,printf
可以在
iostream 术语)。但任何 iostream、区域设置或标准的使用
容器已经过时了,除非你防止递归:
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
执行相同的操作,尽管在
实践中,如果您要记录到文件,我不会期望任何删除
除了在 close()
或析构函数中。
关于c++ - 基本的新建/删除运算符(operator)日志记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12403141/