2013-05-14 32 views
3

有沒有辦法實現operator new的覆蓋旁路?在C++中繞過operator new的覆蓋

事情是這樣的:

void* ::operator new(std::size_t size) { 
    void *p = (::operator new(size)); // But original, _not_ infinite recursion 
    // do stuff with p 
    return p; 
} 

背景: 我有一些遺留代碼,這是我們最近更換了與Visual Studio 2012年。現在,我們得到隨機崩潰時malloc未能_heap_alloc足夠的內存塊編譯。 (是的,這些代碼裏面遍佈着小內存泄漏和其他不良行爲,但不幸的是徹底的清理並不現實,大約500000 SLOC。)

我目前的理論是,原因是幾乎所有源文件包括與operator new下面覆蓋一個標題:

void* ::operator new(std::size_t size) { 
    void* p = malloc(size); 
    if(p == NULL) 
     throw; 
    // set memory to zero 
    memset(p, 0, size); 
    return p; 
}; 

void* ::operator new[](size_t count) throw(std::bad_alloc) { 
    // try to allocate count bytes for an array 
    return (operator new(count)); 
} 

沒有的delete覆蓋。

實質上,這意味着應用程序將使用malloc的分配與使用delete而不是free的取消分配進行混合。

第一次嘗試與Q & d修復: 介紹的使用freedelete覆蓋。但這只是部分幫助,因爲有時包括訂單和鏈接庫仍然讓它搞砸了。

第二次嘗試Q & D修復: 刪除覆蓋。但不幸的是,將存儲器初始化爲0是不必要的。來自使用舊編譯器的遺產,始終這樣做,編程人員使用C++將始終這樣做。

我知道new()會照顧到這一點,但不幸的是,我沒有意識到有任何好的方法可以使用該方法,而無需手動通過所有源代碼並更新它。它也不利於實施不好的類,它假定所有的成員在構造函數中沒有這樣做就會被廢除。

因此,我的第三個想法是Q & D修復: 在覆蓋中使用常規new,正如此問題所詢問的。

+0

在運營商new上使用'= delete'。 8.4.3刪除標準的定義可能會提供更多細節。 – 2013-05-14 09:43:15

+1

無論如何,你的全局'operator new'最有可能是用'malloc'實現的(否則你會在第一次調用delete時崩潰)。所以這個重寫的唯一不同之處就是填滿內存。做你想做的事情不可能有幫助(即使有可能),因爲目前的版本已經做了完全一樣的事情。爲'delete'添加覆蓋不太可能有幫助,因爲當前版本已經做了完全相同的事情(儘管爲了一致性我會這樣做)。 *您需要修復真正的內存錯誤。*沒有辦法解決這個問題。 – 2013-05-14 09:45:04

+0

@ n.m。,感謝您的評論。我檢查了Visual Studio包含的源文件,在我看來'operator new'沒有在MS C++中用'malloc'實現。 'malloc'和'operator new'都是用'_heap_alloc'實現的,但是我的理解有點不同。 – 2013-05-14 11:03:21

回答

2

有沒有一種方法來實現覆蓋操作符new的旁路?

沒有,我所知道的,但你爲什麼不乾脆以同樣的方式做MS在他們的基礎_heap_alloc的實現重新實現它在您的自定義功能,只需添加您的自定義呢?

一個做板上釘釘的分配嘗試不僅是反正不是MS做什麼:

http://msdn.microsoft.com/en-us/library/vstudio/we2zys4d.aspx

的默認行爲是執行一個循環。在循環中, 函數首先嚐試分配請求的存儲空間

無論如何 - 我第二個什麼樣的數據。加入了註釋

您需要解決的實際內存錯誤

這是自地名釋義;對於那些任何調試目的 - 請看看std :: set_new_handler。

順便說一句 - 有一些事情,我覺得很討厭你的代碼

  • 操作的明確資格
  • 不扔的std :: bad_alloc的,但重新拋出的catch塊之外

快樂黑客!

問候,S.

P.S.:@all:我不能在這裏「投了」開始我有限的EXP這個問題,但我建議這樣做。這是一個非常有趣的話題,而且制定得很好。