2014-08-31 18 views
6

我正在嘗試瞭解C++中的內存池以獲得更好的速度和調試功能。我一直在遵循這裏找到的方法:http://oroboro.com/overloading-operator-new/。所以,我已經超負荷newnew[]delete,並delete[]這樣的:在第三方庫中未調用全局過載delete [

inline void* operator new  (size_t size) { return myAlloc(size); } 
inline void* operator new[] (size_t size) { return myAlloc(size); } 
inline void operator delete (void* ptr ) { myFree(ptr); } 
inline void operator delete[](void* ptr ) { myFree(ptr); } 

我喜歡這樣的第三方庫直接使用此版本的new,但我遇到了一個問題。我正在製作使用DXUT的DirectX應用程序。我從我的項目中分別編譯DXUT。最後,它呼籲:

std::unique_ptr<D3D11_SUBRESOURCE_DATA[]> initData(new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ]); 

一旦這種獨特的指針超出範圍,它崩潰上delete[] _Ptr通話,這並沒有經過我的重載運營商去。我嘗試在我的main中添加int* dummy = new int[10]; delete[] dummy;來調試我的內存池實現。建設該項目出現了錯誤,但清理建築工作正常。令我驚訝的是,一切正常,包括崩潰的DXUT系列!

問題1:當我添加解決問題的調試行時究竟發生了什麼?我想因爲某種原因,我的運算符delete []直到我在我自己的應用程序代碼中調用它才知道。這是保證解決問題還是隻是運氣不好?

問題2:我注意到new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ]沒有直接調用我的operator new[],但最終調用我的operator new(無括號)。它仍然在指針上呼叫運營商delete[]。這是否構成問題?我是否必須添加適當的超載,以便我的operator new[]被調用或者這種行爲是否正常?

作爲參考,operator new[]重載被稱爲是:

void * __CRTDECL operator new[](::size_t count, const std::nothrow_t& x) 
_THROW0() 
{ // Try to allocate count bytes for an array 
    return (operator new(count, x)); 
} 

回答

4

問題1:當我加入了調試行 固定的問題,到底發生了什麼?我猜是因爲某種原因,我的運算符delete []不是 ,直到我在我自己的應用程序代碼中調用它爲止。這是保證 解決問題還是隻是運氣不好?

§3.2[basic.def.odr]/P4:

內聯函數應每翻譯單元,其中 它是ODR使用的限定。

聽起來好像是因爲它不是你的主要翻譯單元使用,並標註inline(這意味着編譯器可以假設你的編譯器不產生全球operator delete[]代碼,使用它們會有一個任何翻譯單元他們的定義)。但是,單獨編譯的庫沒有這些函數的定義,並且最終使用了標準庫中的默認值。使他們不是inline應該解決這個問題。

問題2:我注意到new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ]沒叫我 operator new[]直接,但最終還是叫我operator new(無 括號內)。它仍然在指針上呼叫運營商delete[]。 這是否構成問題?我是否必須添加適當的過載,例如 ,我的operator new[]被調用或者這種行爲是否正常?

兩個投擲和nonthrowing的operator new []版本,以及爲operator new的nonthrowing版本的默認版本,指定調用operator new投擲版本,以得到存儲。所以你在那裏安全。但是,您的operator new的定義可能是錯誤的。他們必須返回一個有效的指針或拋出異常。不允許返回空指針。

+0

刪除內聯並將代碼放入實現文件而不是頭文件!我想知道爲什麼我複製的鏈接沒有提到它的任何內容。 – DSM 2014-08-31 23:06:33