2012-10-31 9 views
14

Ho due blocchi di codice su new[] e delete[]:Dopo p = nuova stringa [0] e p = nuova int [0], perché la versione della stringa si blocca quando si cancella [] p?

1)

#include <string> 

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

    return 0; 
} 

2) In questo caso, mi limito a cambiare std::string a int

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

    delete[] p; 

    return 0; 
} 

La mia domanda è:

Perché i primi programma va in crash con il seguente messaggio (in ambiente Linux):

Segmentation fault (core dumped) 

ma il secondo programma funziona bene senza alcun errore?

EDIT

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

mi basta usare g++ senza alcun argomento per compilarlo.

Se si tratta di un errore del compilatore, dovrebbero verificarsi un arresto anomalo o non conforme allo standard?

+2

Sembra un bug del compilatore – Andrey

+1

Esso non va in crash qui. Quale compilatore stai usando (con la versione esatta) e come lo stai compilando? – amaurea

+1

Crash con g ++ (4.7 e 4.8), non si blocca con clang. Immagino sia un bug g ++. – kennytm

risposta

13

Questo dovrebbe essere un bug di gcc. Che l'intera espressione new[] sia ignorata e che p non sia inizializzata, e quindi abbiamo delete[] un puntatore non inizializzato che si arresta in modo anomalo. Se si compila il programma con -Wall esso vi avvertirà che

avvertimento: ‘p’ viene utilizzato non inizializzati in questa funzione

che è chiaramente sbagliata. L'espressione new X[0] è ben definita in C++ 03 e C++ 11 (§5.3.4/7), e funziona correttamente in clang, quindi l'unica conclusione logica è che si tratta di un bug gcc.


L'eliminazione-di- new[] problema esiste solo quando il tipo di essere costruito ha alcun costruttore non banale. E il segfault accade che il tipo ha un distruttore, perché il delete[] avrà quindi bisogno di dereferenziare quel puntatore non inizializzato. Di conseguenza, si blocca per std::string ma non, perchéè banale e non lo è std::string.


Questo può essere lavorato in giro usando una variabile intermedia, in modo tale che l'espressione non può essere valutata a 0 direttamente:

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

Sono sorpreso dell'hack funziona ... In liveworkspace ho 3 comportamenti: codice OP originale (avvertenza + crash), questo aggiramento (nessun avvertimento, nessun crash), usando 'size_t const length = 0;' (warning, nessun incidente). I * love * gcc ... –

Problemi correlati