2013-08-04 8 views
5
int* arr = new int[count]; 

delete arr; 

Perché funziona? Ho controllato e in realtà libera la memoria. Da quello che ho letto ho bisogno di delete[] arr; altrimenti non libererà tutta la memoria.C++ cancella la memoria dell'array senza parentesi ancora funziona?

+1

AFAIK questo è UB. – Borgleader

+3

"Perché funziona?" - no, sembra funzionare. –

+0

Senza le parentesi, si chiama solo un distruttore, non tutti i distruttori dell'array. Vedi anche http://stackoverflow.com/questions/2425728/delete-vs-delete-operators-in-c – GreatBigBore

risposta

7

Ora provate con riempimento della matrice con stringhe di 100 byte ciascuno, e vedere se libera ancora tutta la memoria allocata ...

È comportamento indefinito, e come sempre, apparirà talvolta UB lavorare. Nel tuo caso, non hai un distruttore per gli oggetti nella memoria, quindi non c'è "ulteriore lavoro", solo libera tutta la memoria [1]. Ma se hai un oggetto che ha un distruttore che fa qualcosa di utile, non verrà chiamato (probabilmente).

È consigliabile utilizzare SEMPRE delete [] se si utilizza new T[size]; da allocare. Non mescolare i due, è sempre sbagliato - solo a volte FUNZIONA per funzionare [proprio come ALCUNE misure di chiavi in ​​pollici funzionano con dadi mm e viceversa - ma è ancora sbagliato usare una chiave inglese impostata sui dadi metrici].

[1] Si noti che questo potrebbe funzionare per questa particolare combinazione di librerie compilatore/C++. La compilazione con un compilatore diverso, l'utilizzo di una diversa libreria C++ o la compilazione per un diverso sistema operativo può causare il crash quando si tenta la stessa cosa.

3

eliminare e cancellare [] sono in realtà operatori diversi e utilizzare quello sbagliato è sempre un errore. Il problema è che spesso sembra buono al momento, ma l'heap si è corrotto e molto probabilmente si verificherà un incidente apparentemente non correlato in seguito.

+0

Non capisco perché sono stato contrassegnato per questo poiché è VERO. Si potrebbe provare a eseguire valgrind o un analogo strumento di analisi della memoria e mostrerà il danneggiamento dell'heap quando si verifica. –

+1

Spero che i commenti dei downvoters. Mi interessa quale parte potrebbe non essere corretta. – user2029077

+0

Non so perché: questa è una risposta completamente accurata. – Puppy

6

La differenza non è se non la memoria allocata viene liberata correttamente - se si utilizza

delete 

o

delete[] 

la memoria sarà ancora correttamente deallocato.

La differenza è se i distruttori saranno o meno correttamente richiamati.

delete // will only invoke the destructor of the first element of the array. 

delete[] // will invoke the destructor for *each* element of the array. 

Questo non ha alcun effetto pratico per i tipi primitivi come int o float, ma quando si ha una matrice di una classe, la differenza può essere critico.

+0

Posso immaginare un'implementazione dove questo sarebbe vero. Avete una documentazione effettiva di un'implementazione che dimostri che è vero? – sehe

+2

Nessun documento, solo la mia esperienza in questo è con Visual C++. È passato un po 'di tempo, ma ricordo di aver riscontrato dei bug perché ho usato erroneamente delete invece di delete []. Abbastanza sicuro che si sia comportato come ho descritto ... tenere presente che * x dereferenze nella stessa posizione di x [0] e dichiarare x come puntatore a qualsiasi cosa non dice se l'oggetto di destinazione è scalare o array, quindi l'operatore di cancellazione non saprà che deve distruggere una matrice di oggetti rispetto a un oggetto scalare a meno che non glielo comunichi tramite il costrutto di eliminazione appropriato. – Zenilogix

Problemi correlati