[英]Basic new/delete operator logging
我想重载全局和非全局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
。 当然,很多人没有理由动态分配,而且我不必担心诸如memcpy
或strlen
类的函数。 实际上,使用C库中的任何函数都可能是安全的(尽管从理论上讲,可以使用iostream
来实现printf
)。 但是,除非可以防止递归,否则对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
进行相同的operator delete
,尽管在实践中,如果您要登录到文件,除了close()
或析构函数之外,我不希望有任何delete
。
您可以重新定义new
关键字以调用其他签名并传递__FILE__
等。
在一般情况下,这可以解决。 当您开始使用覆盖operator new
对象时,虽然有点麻烦。
如果我能通过记忆知道这一点,我会分享,但是您可能可以在Google上找到它。 我认为在某个地方的codeproject上有一个实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.