[英]Basic new/delete operator logging
I'd like to overload global and non-global new/delete operators for logging. 我想重载全局和非全局new / delete运算符以进行日志记录。
As I just want to add logging informations, I'd like to keep the standard behavior of this operators. 当我只想添加日志记录信息时,我想保留此运算符的标准行为。
Is there a way to overload new/delete operator to add logging but without having to rewrite the standard behavior (which might be error prone) ? 有没有一种方法可以使new / delete运算符超载以添加日志记录,而不必重写标准行为(可能容易出错)?
Actually, I not only need standard behavior. 实际上,我不仅需要标准行为。 I need the same behavior as Visual 2010 implementations, which might be not standard.
我需要与Visual 2010实现相同的行为,这可能不是标准的。
The kind of error I am looking for with this kind of logging is new[]/delete mismatch. 我正在用这种日志记录寻找的错误类型是new [] / delete mismatch。
I could use classic tools but they slowdown the execution and I'd like to share the binary with other people to gather more informations. 我可以使用经典工具,但是它们会降低执行速度,并且我想与其他人共享二进制文件以收集更多信息。
You can use malloc
/ free
for the basic allocation. 您可以使用
malloc
/ free
进行基本分配。 Handling full standards compliance for new
is a bit tricky; 处理
new
标准的完整标准有些棘手; you need something like: 您需要类似:
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;
}
Often, however, you don't need such full compliance. 但是,通常,您不需要如此完全的合规性。 If you say that you don't support setting the
new_handler
, for example, you can simplify greatly. 例如,如果您说不支持设置
new_handler
,则可以大大简化。 In the overloaded version I use for testing, in fact, if malloc
really fails, I abort (but this version has options to trigger a failure of new
, on demand, since I want to test that my code reacts correctly to it as well). 实际上,在我用于测试的重载版本中,如果
malloc
确实失败,我会中止(但是该版本具有按需触发new
失败的选项,因为我也想测试我的代码也能正确响应) 。
If you're logging, be very careful to avoid endless recursion. 如果您正在记录日志,请非常小心,以避免无限递归。 The only functions guaranteed not to use
operator new
in the standard library are malloc
and free
. 保证不使用标准库中的
operator new
的唯一函数是malloc
和free
。 Of course, a lot have no reason to allocate dynamically, and I don't worry about functions like memcpy
or strlen
. 当然,很多人没有理由动态分配,而且我不必担心诸如
memcpy
或strlen
类的函数。 In practice, you are probably safe with any of the functions in the C library (although in theory, printf
could be implemented in terms of iostream
). 实际上,使用C库中的任何函数都可能是安全的(尽管从理论上讲,可以使用
iostream
来实现printf
)。 But any use of iostream, locale or the standard containers is out, unless you protect against recursion: 但是,除非可以防止递归,否则对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;
}
Formally, you should do the same for operator delete
, although in practice, if you're logging to a file, I wouldn't expect any delete
except in close()
or the destructor. 正式地,您应该对
operator delete
进行相同的operator delete
,尽管在实践中,如果您要登录到文件,除了close()
或析构函数之外,我不希望有任何delete
。
You can redefine the new
keyword to call a different signature and pass __FILE__
and such. 您可以重新定义
new
关键字以调用其他签名并传递__FILE__
等。
In the general case this works out OK. 在一般情况下,这可以解决。 When you start using objects that override
operator new
though you kinda screw yourself. 当您开始使用覆盖
operator new
对象时,虽然有点麻烦。
If I knew it by memory I'd share, but you can probably find with google. 如果我能通过记忆知道这一点,我会分享,但是您可能可以在Google上找到它。 I think there's an implementation on codeproject somewhere.
我认为在某个地方的codeproject上有一个实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.