我想重载全局和非全局 new/delete 运算符以进行日志记录。
由于我只想添加日志信息,因此我想保留此操作员的标准行为。
有没有办法重载 new/delete 运算符来添加日志记录,但不必重写标准行为(这可能容易出错)?
实际上,我不仅需要标准的行为。我需要与 Visual 2010 实现相同的行为,这可能不是标准的。
我在这种日志记录中寻找的错误类型是 new[]/delete mismatch。
我可以使用经典工具,但它们会减慢执行速度,我想与其他人共享二进制文件以收集更多信息。
我想重载全局和非全局 new/delete 运算符以进行日志记录。
由于我只想添加日志信息,因此我想保留此操作员的标准行为。
有没有办法重载 new/delete 运算符来添加日志记录,但不必重写标准行为(这可能容易出错)?
实际上,我不仅需要标准的行为。我需要与 Visual 2010 实现相同的行为,这可能不是标准的。
我在这种日志记录中寻找的错误类型是 new[]/delete mismatch。
我可以使用经典工具,但它们会减慢执行速度,我想与其他人共享二进制文件以收集更多信息。
您可以使用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。当然,很多没有理由动态分配,我也不担心memcpyor
之类的函数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形式上delete
,您应该为close().
您可以重新定义new关键字以调用不同的签名并通过__FILE__等。
在一般情况下,这可以正常工作。当您开始使用覆盖的对象时,operator new尽管您有点自欺欺人。
如果我是凭记忆知道的,我会分享,但您可能可以通过 google 找到。我认为在某个地方的 codeproject 上有一个实现。