c++ - 基本的新建/删除运算符(operator)日志记录

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

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

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

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

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

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

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

最佳答案

您可以使用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 失败,因为我想测试我的代码 也能正确 react )。

如果您正在记录日志,请非常小心,避免无休止的递归。唯一的 保证函数不使用标准库中的operator newmallocfree。当然,很多都没有理由分配 动态地,我不担心像 memcpystrlen。实际上,您可能可以安全地使用任何功能 在 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 执行相同的操作,尽管在 实践中,如果您要记录到文件,我不会期望任何删除 除了在 close() 或析构函数中。

关于c++ - 基本的新建/删除运算符(operator)日志记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12403141/

相关文章:

c++ - 不需要时静态初始化

c++ - 在保存到 RAD Studio 之前获取修改后的文件

c++ - 虚运算符重载 C++

c++ - 我想我可以理解 N4140 中的 §5.3.4/11,但是扩展的分配函数的概念对我来说是不可理解的

c++ - 分配数组时 operator new 的问题

c++ - 为什么编译器不能为这个函数引用找出正确的重载?

c++ - 具有抽象继承的后缀运算符++

c++ - 重载预增量运算符时是否必须返回对对象的引用?

c++ - 为什么我可以覆盖 -(否定)和! (不是)但不是~(按位不是)?

c++ - C++中的删除操作