2012-11-07 54 views
3

我想用更健壯的分配器替換標準分配器(C++標準只需要對vector :: resize進行溢出檢查)。提供許多庫的各種C++分配器在進行負面自我測試時,會在他們的臉上變得平坦。替換標準C++分配器?

我有權訪問更健壯的分配器。 ESAPI的分配器不僅檢查溢出,還有調試工具來幫助發現錯誤。 http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/zAllocator.h

有沒有一種標準的方法來替換程序中使用的C++分配器,而不需要太多的努力?我也想確保它被替換爲庫代碼,我可能無法訪問源代碼。

+1

AFAIK,所有標準容器構造函數都採用可選的分配器。 – chris

+0

是的。如何在不訪問每個源文件中的每個聲明的情況下全面替換它? – jww

+0

我敢肯定,如果聲明是一致的,那麼有一些正則表達式很容易做到。即使不是,您也可以解釋具體的不一致之處。 – chris

回答

3

malloc不同,它是一個庫函數,可以被另一個具有相同簽名的函數替換,std::allocator是一個類模板,模板代碼根據需要實例化並內聯到使用它的代碼中。一些標準庫代碼已經被編譯到庫的目標文件中,並且將包含不能替換的實例化的std::allocator代碼。所以唯一的辦法是如果標準庫提供一些非標準的方法來替換它的std::allocator。幸運的是,海灣合作委員會的libstdC++可以讓你做到這一點,讓你選擇用於std::allocator實施GCC的配置和構建時,有幾個different choices

它不會是太大的工作到ESAPI分配器添加到GCC源作爲選項之一,然後重建GCC以使用該分配器作爲std::allocator的基類,提供其實施。您可能需要稍微調整ESAPI分配器代碼,也許可以更改libstdC++腳本以允許您說出--enable-libstdcxx-allocator=esapi

+0

很酷,謝謝喬納森。 「您可能需要稍微調整ESAPI分配器代碼」 - 考慮到您對我們的幫助有多大,如果不需要調整,我不會感到驚訝。 – jww

4

在C++ 0x中,在名稱空間mystd中定義一個新的模板別名,它是一個std::vector,但是使用您的自定義分配器。將所有std::vector s替換爲mystd::vector。擺脫你代碼中的所有using namespace stdusing std::vector

重建。將您使用原始vector<T>的地方替換爲mystd::vector<T>

噢,並且使用比mystd更好的名字。

+0

std :: allocator是弱鏈接的嗎?我可以通過提供一個強大的鏈接符號來結束嗎? – jww

+0

這是一個模板,而不是可以鏈接的符號。 –

4

如果您想要在全局基礎上而不是按容器修改分配,那麼您可能需要替換::operator new::operator delete。可以想象,你還需要替​​換::operator new[]::operator delete[] - 但這些僅用於分配陣列,你應該幾乎從不使用(除非是不明顯的情況:不,這些是而不是用於爲std::vector分配內存,儘管它在某些方面與數組非常相似)。

儘管試圖替換庫的大部分部分是被禁止的,但該標準特別允許替換這些。

當然,如果有人已經指定不同的分配特定的容器,並且分配不(最終)通過::operator new(或::operator new[])得到它的內存,這將不會影響集裝箱/這些容器。

+0

謝謝傑瑞。我不認爲有一種簡單的方法可以像分配器那樣簡單地執行此操作。我知道無法輕鬆處理所有不同的元素插入點。我準備從我的控制下的代碼庫中禁止STL代碼(我希望有一個安全思想的選擇)。 – jww

+0

注意以後的參考,[這裏是如何替換操作符](http://en.cppreference.com/w/cpp/memory/new/operator_new)。似乎很簡單,如果沒有額外的警告... – Eonil