2012-03-13 93 views
12

我試圖通過向new[]傳遞一些否定參數來測試bad_alloc異常。當傳遞小負數時,我得到了我所希望的 - bad_alloc。但是,當通過-1時,我可以看到我的對象構建了數千次(我在構造函數中打印了靜態計數器),並且應用程序以segfault終止。爲什麼new [-1]產生段錯誤,而new [-2]產生bad_alloc?

new[]轉換符號整數size_t,所以-1size_t最大和-2maximum - 1等。

那麼,爲什麼得到了一些巨大的數字時new[]拋出異常,但會嘗試接收size_t最大何時分配? 1111...11111...0之間爲new[]有什麼不同? :)

在此先感謝!

+2

哪個編譯器/編譯器的版本/ OS/... – xanatos 2012-03-13 09:09:52

+0

那次我錯過了答案,因爲StackOverflow沒有發送任何通知,現在我不能重現問題......我後悔我沒有生成核心轉儲,也沒有調查它......現在我無法重現問題 - 傳遞-1到'新'似乎工作,並拋出異常,而傳遞max int分配了很多的對象,但不seg段。我開始認爲問題在別的地方......我爲他的嘗試給了神祕的加號。 – flyjohny 2012-09-07 10:40:43

回答

17

這裏是我的胡亂猜測:

在很多實現的,分配器將放在旁邊的分配區域的一些元數據。
(例如,分配的大小。)實際上,分配的數量超過了您要求的數量。

我們假設size_t是32位。編譯爲32位。


當你這樣做:

int *array = new int[-1]; 

-1成爲-1 * 4 bytes = 4294967292(溢出後)。但是,如果分配器實現將4字節的元數據放在分配的區域旁邊。實際尺寸變爲:

4294967292 + 4 bytes = 0 bytes (after overflow) 

所以0字節實際分配。

當您嘗試訪問內存時,由於您立即跳出界限,因此出現段錯誤。


現在讓我們說你做:

int *array = new int[-2]; 

-2成爲-2 * 4 bytes = 4294967288(溢出後)。追加4個字節的元數據,你會得到4294967288 + 4 = 4294967292

當分配器從操作系統請求4294967292字節時,它被拒絕。所以它會拋出bad_alloc


因此,基本上,它可能是-1-2使之間是否分配器附加其元數據後,將溢出的差異。

+0

我從來沒有在野外看到過這樣的越野車實現 – PlasmaHH 2012-03-13 09:33:55

+0

+1。 「當你嘗試訪問內存時 - 」你「是'new []'繼續循環它認爲它分配空間的元素,調用位置'new'來調用每個構造函數.... – 2012-03-13 09:34:44

+0

@ PlasmaHH這就是我的想法。我試圖找到一個來源,告訴我這是否是未定義的行爲。但我還沒有找到任何東西。 – Mysticial 2012-03-13 09:37:32