【问题标题】:Basic new/delete operator logging基本的新/删除操作员日志记录
【发布时间】:2012-09-13 09:21:27
【问题描述】:

我想重载全局和非全局 new/delete 运算符以进行日志记录。

由于我只想添加日志记录信息,因此我想保留此运算符的标准行为。

有没有办法重载 new/delete 运算符来添加日志记录,但不必重写标准行为(这可能容易出错)?

其实,我不仅需要标准的行为。我需要与 Visual 2010 实现相同的行为,这可能不是标准的。

我在这种日志记录中寻找的错误类型是 new[]/delete mismatch。

我可以使用经典工具,但它们会减慢执行速度,我想与其他人共享二进制文件以收集更多信息。

【问题讨论】:

  • 我相信,如果你只调用 malloc ,你将保持标准行为。是否保留要替换的 operator new 的精确行为是另一回事。
  • 到目前为止有什么尝试吗?您在尝试中遇到了哪些问题?
  • 默认行为并不是非常复杂,所以我不会担心。如果你做得好,我想会有一个循环并调用get_new_handler。确保不要在分配函数中使用标准容器,除非你给它们一个不同的分配器,它本身不使用operator new
  • @john 谢谢,我在我的问题中添加了信息,我不仅需要标准行为,还需要与 Visual 2010 实现相同的行为。
  • this excellent FAQ question 你会发现编写你自己的标准符合operator new/delete 并不真正涉及,只需大约5-10 行样板,加上你的日志功能和对@ 的调用987654325@.

标签: c++ operator-overloading new-operator delete-operator


【解决方案1】:

您可以使用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。当然,很多没有理由分配 动态的,我不担心像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 做同样的事情,尽管在 练习,如果您要登录到文件,我不希望有任何 delete close() 或析构函数除外。

【讨论】:

    【解决方案2】:

    您可以重新定义 new 关键字以调用不同的签名并传递 __FILE__ 等。

    在一般情况下,这可以正常工作。当您开始使用覆盖 operator new 的对象时,尽管您自己有点搞砸了。

    如果我是凭记忆知道的,我会分享,但您可能可以通过 google 找到。我认为在某个地方的 codeproject 上有一个实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-15
      • 1970-01-01
      相关资源
      最近更新 更多