You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Linux C++程序中获取重载new运算符的源码调用位置?

解决Linux C++重载new获取调用位置的方案

要在不使用调用栈的前提下获取new运算符的源码调用位置,你可以通过宏替换+重载带位置参数的operator new实现,具体步骤如下:

1. 重载带文件、行号参数的operator new

首先重载支持传入文件路径和行号的operator new(包括普通版本和数组版本),在函数内记录位置信息:

#include <cstdlib>
#include <iostream>

// 重载普通new,接收文件和行号参数
void* operator new(size_t size, const char* file, int line) {
    void* ptr = malloc(size);
    // 这里可以将内存地址、大小、文件、行号存入日志或全局统计结构
    std::cout << "Allocated " << size << " bytes at " << file << ":" << line << std::endl;
    return ptr;
}

// 对应数组new的重载
void* operator new[](size_t size, const char* file, int line) {
    return operator new(size, file, line);
}

2. 用宏替换默认new

通过预处理器宏,将所有普通new调用自动替换为带位置参数的形式:

#define new new(__FILE__, __LINE__)
#define new[] new[](__FILE__, __LINE__)

这样当你写Foo* p = new Foo;时,预处理器会将其替换为Foo* p = new(__FILE__, __LINE__) Foo;,自动调用我们重载的带参数版本,编译期就注入了文件和行号信息,完全没有运行时调用栈的开销。

为什么你之前的默认参数方案失效?

C++标准规定,普通的new T语法只会匹配operator new(size_t)签名的重载。带额外参数的operator new必须通过placement new语法(new(参数) T)才能触发,因此你写的带默认参数的版本不会被普通new调用,自然无法生效。

额外注意事项

  • 如果需要支持delete时关联位置信息,可以考虑在分配内存时将位置信息和内存地址绑定,释放时查询对应记录。
  • 若代码中存在显式的placement new调用,需要避免宏替换冲突,可以用#undef new临时取消宏定义,用完再恢复。

内容的提问来源于stack exchange,提问作者Baruian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 13:10:27