2012-02-11 12 views
14

ho scoperto la classica nuova eliminare l'errore/mancata corrispondenza nel nostro codice di base come segue:Quanto è grave l'errore di disallineamento dell'operatore new/delete?

char *foo = new char[10]; 

// do something 

delete foo; // instead of delete[] foo; 

quanto grave è questo? Provoca una perdita di memoria o un errore? Quali sono le conseguenze. Abbiamo alcuni problemi di memoria, ma questo non sembra abbastanza serio per spiegare tutti i nostri sintomi (heap corruzione ecc)

EDIT: domande in più per la chiarezza
Ha solo liberare il primo membro della matrice? oppure
Fa in modo che il sistema perda traccia dell'array? o
La memoria corrotta è in qualche modo?

risposta

16

È un comportamento non definito serio (potrebbe funzionare, potrebbe bloccarsi, potrebbe fare qualcos'altro).

+0

Grazie per la risposta rapida. Quindi davvero indefinito? Come in, nessuno può dire cosa potrebbe accadere? Se è così, potrebbe spiegare le nostre osservazioni. –

+0

@AndrewS. Anzi indefinito. Mi ricordo che "ha funzionato" in Visual Studio per esempio. – cnicutar

+2

Non definito, ovvero dipende dal compilatore/sistema operativo. –

8

A prima vista, chiamare delete anziché delete[] non dovrebbe essere molto cattivo: si distrugge il primo oggetto e si provoca una perdita di memoria.

MA: allora, delete (o delete[]) chiama free per liberare la memoria. E free ha bisogno del suo indirizzo assegnato originariamente, per liberare correttamente la memoria. Oppure, il fatto è che mentre new restituisce l'indirizzo originale assegnato da malloc, new[] restituisce un indirizzo diverso.

La chiamata gratuita all'indirizzo restituito da new[] provoca un arresto anomalo (libera memoria in modo caotico).

vedere questi legami molto istruttivi per una migliore comprensione:

http://blogs.msdn.com/b/oldnewthing/archive/2004/02/03/66660.aspx#66782

http://web.archive.org/web/20080703153358/http://taossa.com/index.php/2007/01/03/attacking-delete-and-delete-in-c

Da questi articoli è anche ovvio perché chiamando delete[] anziché eliminare è anche una pessima idea.

Quindi, per rispondere: sì, si tratta di un errore molto grave. Corrompe la memoria (dopo aver chiamato solo il distruttore del primo oggetto).