【问题标题】:C++ operator new overloading, compilation errorC++运算符new重载,编译错误
【发布时间】:2017-03-06 11:51:36
【问题描述】:

当我全局重载 new 运算符以跟踪内存泄漏时,在以下位置出现编译错误

 ::new(__tmp) _Rb_tree_node<_Val>;

看起来他们在那里分配和填充节点。 以下是错误:

/home/symbol/Android/Sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/include/functional: In static member function 'static void std::_Function_base::_Base_manager<_Functor>::_M_clone(std::_Any_data&, const std::_Any_data&, std::true_type)':/home/symbol/Android/Sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/include/functional:1870:9: error: '__dest' does not name a type
new (__dest._M_access()) _Functor(__source._M_access<_Functor>());

下面是我的重载代码:

void* operator new(std::size_t sz,char const* file, int line){  
return newImpl(sz,file,line);
}

void* operator new [](std::size_t sz,char const* file, int line){  
return newImpl(sz,file,line);
}

void operator delete(void* ptr) noexcept{
auto ind=std::distance(myAlloc.begin(),std::find(myAlloc.begin(),myAlloc.end(),ptr)    );
myAlloc[ind]= nullptr;
free(ptr);
}

#define new new(__FILE__, __LINE__)

【问题讨论】:

  • 宏定义看起来不对。生成预处理器输出以查看该宏在代码中扩展为什么,这可能不是您所期望的。
  • 如果您仍然使用宏,为什么还需要重载?你可以用任何函数调用替换new

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


【解决方案1】:
#define new new(__FILE__, __LINE__)

这是非法的。在标准下,带有关键字#defined 的程序的行为是未指定的。您的程序格式不正确,不需要诊断。

如果你想知道为什么要打破这个特定的时间,那是因为 C++ 标准库本身使用placement new,它传递了一个要构造的空指针。

您的代码采用启动放置新表达式的裸new,并将其替换为不同的放置新表达式。这使得其余的代码变得毫无意义,正如我们得到的那样:

new("some file", 1234) (some void pointer) some_type( constructor_args... )

这是完全非法的语法。

如果您想捕获 99% 的分配,请在创建 std 容器时重新调整您的代码以使用不同的分配器。扫一扫您的代码,将非展示位置的 new 替换为您可以合法的 #define 到不同的东西(例如 TRACED_NEWTRACED_NEW_PLACEMENT 用于展示位置新)。

在你的分配器中使用这些。

std::containers 的所有使用替换为使用分配器的所有使用的一种方法是编写自己的notstd 命名空间,并使用替换分配器的模板别名(或您想要做的任何其他重组)。然后,此自定义分配器可以使用您的 TRACED_NEW_PLACEMENTTRACED_NEW

结果是一个定义明确的程序,而不是一个 hack,目前充其量只能与您当前的编译器一起使用。

【讨论】:

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