繁体   English   中英

基本的新/删除操作员日志

[英]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的唯一函数是mallocfree 当然,很多人没有理由动态分配,而且我不必担心诸如memcpystrlen类的函数。 实际上,使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM