2017-03-06 98 views
0

當我重載新的運營商在全球範圍內跟蹤MEM泄漏,我得到的編譯錯誤在以下地方C++運算符重載新,編譯錯誤

::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__) 
+1

宏定義看起來不正確。生成預處理器輸出以查看代碼中該宏擴展的內容,這可能不是您所期望的。 –

+0

爲什麼你需要超載如果你使用宏呢?你可以用任何函數調用來替換'new' – Ap31

回答

2
#define new new(__FILE__, __LINE__) 

這是非法的。在該標準下,具有關鍵字#defined的程序的行爲是未指定的。你的程序不合格,不需要diangostic。

如果你想知道爲什麼你打破這個特定的時間,那是因爲C++標準庫在它傳遞一個要構造的void指針的地方使用了placement new本身。

您的代碼採用裸露的new開始展示位置新表達式,並用不同的展示位置新表達式替換它。然後讓剩下的代碼廢話,因爲我們得到:

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

這是完全非法的語法。

如果您想要捕獲99%的分配,請在創建std容器時重新創建代碼以使用不同的分配器。掃一掃您的代碼,將您的代碼new替換爲您可以合法地#define改爲不同的東西(例如TRACED_NEWTRACED_NEW_PLACEMENT)。

在分配器使用這些。與使用分配器的貨物更換的std::container一切都使用

一種方法是寫自己的notstd命名空間模板別名更換分配器(或任何其他換裝你想做的事)。這個自定義分配器然後可以使用您的TRACED_NEW_PLACEMENTTRACED_NEW

而結果是一個定義良好的程序,而不是目前最適用於當前編譯器的破解程序。