C++ 如何在重载"new"运算符中获取行号和函数名称



我想在多线程环境中超载新操作员,并希望在其中拥有线程ID,函数名称和行号。有什么方法可以做到吗?

您可以做一个新的operator new超载:

void * operator new(std::size_t count, const char* file, int line)
{
    // Do stuff
    // ...
    return ::operator new(count);
}
void * operator delete(void* p, const char* file, int line)
{
    // Do stuff
    // ...
    return ::operator delete(p);
}
// ... and [] versions ..

然后您可以使用放置语法:

auto x = new (__FILE__, __LINE__) Foo;

然后您可以添加一个宏:

#define TRACE_NEW new (__FILE__, __LINE__)
auto x = TRACE_NEW Foo;

一般来说,没有办法做您想做的事(当然,除了使用Moldbnilo之类的宏或未来的STD :: source_location之类的宏)

但是,如果您使用的是最近的Linux系统,并且如果您使用的所有代码(以及它使用的大多数库,包括libstdc++),则使用调试选项编译,您也可以考虑Ian Taylor的Libbacktrace(也可以使用它在GCC中)并在operator new实现中使用它。libbacktrace使您可以使用矮人调试信息检查呼叫堆栈中的通话帧。

您甚至可以在呼叫堆栈中具有大多数功能的源位置(尤其是operator new呼叫者中的源位置)。

请记住,您可以使用调试信息(例如-g)和一些优化标志(例如-O1-O2)编译一些C 代码(使用GCC或Clang);当然,调试信息(在矮人中)将是"模糊的",但在实践中仍然大多可用。

顺便说一句,也许您只需要使用-fsanitize=address仪器选项来编译valgrind或某些地址进行消毒(我们不知道,因为您的问题没有动机)。

最新更新