2012-10-31 34 views
14

我有兩個代碼塊約new[]delete[]在p = new string [0]和p = new int [0]之後,爲什麼字符串版本在delete [] p時崩潰?

1)

#include <string> 

int main() 
{ 
    std::string *p = new std::string[0]; 
    delete[] p; 

    return 0; 
} 

2)在這種情況下,我僅改變std::stringint

int main() 
{ 
    int *p = new int[0]; 

    delete[] p; 

    return 0; 
} 

我的問題是:

爲什麼第一個程序在Linux環境下發生以下消息:

Segmentation fault (core dumped) 

但是第二個程序運行正常,沒有任何錯誤?

編輯

編譯:g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2

我只是用g++不帶任何參數進行編譯。

如果它是一個編譯器錯誤,它們應該按照標準崩潰還是不崩潰?

+2

貌似編譯器故障 – Andrey

+1

它不這裏崩潰。你正在使用哪種編譯器(使用確切版本)以及如何編譯它? – amaurea

+1

g ++(4.7&4.8)崩潰,不會與鏗鏘聲崩潰。我想這是一個g ++的錯誤。 – kennytm

回答

13

這應該是一個海灣合作委員會的錯誤。整個new[]表達式被忽略,並且p變爲未初始化,然後我們delete[]一個未初始化的指針崩潰。如果我們-Wall編譯程序會提醒你,

警告:「P」是在這個函數

這顯然是錯誤的使用未初始化。表達式new X[0]在C++ 03和C++ 11(§5.3.4/ 7)中都有很好的定義,並且這在鏗鏘聲中是正確的,所以唯一合乎邏輯的結論是它是一個gcc錯誤。當要被構造的該類型具有任何非平凡構造只存在


消除-OF- new[]錯誤。而段錯誤發生的類型有一個析構函數,因爲delete[]將需要取消引用該未初始化的指針。因此,它崩潰的std::string但不是int,因爲int是微不足道的,std::string不是。


這可以圍繞通過使用中間變量,使得表達式不能進行評估,以0直接被加工:

size_t length = 0; 
std::string* p = new std::string[length]; 
// ... 
delete[] p; 
+0

我很驚訝的黑客作品...在liveworkspace我有3個行爲:原始OP代碼(警告+崩潰),這種解決方法(沒有警告,沒有崩潰),使用'size_t const length = 0;'(警告,沒有崩潰)。我*愛* gcc ... –

相關問題