2009-11-17 16 views
7

Dopo che faccio, dicoC++ gamma eliminare sintassi operatore

Foo* array = new Foo[N];

Ho sempre eliminati in questo modo

delete[] array;

Tuttavia, a volte ho visto in questo modo:

Come sembra compilare e funzionare (almeno in msvc2005), mi chiedo: Qual è il modo giusto per farlo? Perché compila dall'altra parte, allora?

risposta

13

È possibile controllare questo collegamento MSDN: delete[N] operator. Il valore è ignorato.

EDIT Ho provato questo codice di esempio su VC9:

int test() 
{ 
    std::cout<<"Test!!\n"; 
    return 10; 
} 

int main() 
{ 
    int* p = new int[10]; 
    delete[test()] p; 
    return 0; 
}; 

uscita è: prova !!

Quindi l'espressione viene valutata ma il valore di ritorno viene ignorato. Sono sorpreso a dir poco, non riesco a pensare a uno scenario per cui è necessario.

+0

+1. informazioni utili –

+0

significa che è possibile eliminare [2N] array; e che avrebbe compilato –

+0

Grazie, questo è quello che stavo cercando. – raven

5

delete[] array; è la forma corretta.

4

Il modo giusto è quello di fare delete[] array;. Non sapevo nemmeno che lo delete[N] array; si sarebbe compilato (e dubito che dovrebbe).

+1

Compilare su VC9 con un 'avviso C4208: estensione non standard utilizzata: elimina [exp] - exp valutata ma ignorata' Non intendo ciò che significa – Naveen

+1

Significa che il codice è (1) non valido C++ e (2) l'espressione 'N' è valutata ma ignorata. Questo è abbastanza irrilevante, ma descrive cosa succede se scriveste 'delete [N ++] array;' - N viene prima incrementato e poi ignorato. – MSalters

+0

In realtà, viene prima ignorato e poi incrementato :) – raven

5

Se il secondo caso è giusto o meno, consiglierei di usare il primo perché meno incline agli errori.

Visual Studio compila un sacco di cose che non dovrebbe.

+4

"Visual Studio compila un sacco di cose che non dovrebbe." Amen. – sbi

10

delete [N] array non valido. Non è definito nello standard C++: la sezione 5.3.5 definisce un'espressione di eliminazione come delete expr o delete [] expr e nient'altro. Non si compila su gcc (versione 4.1.2). Per quanto riguarda il motivo per cui viene compilato in Visual C++: chiedere a Microsoft.

+0

Quale standard C++? E, hai un link/ref, dove puoi trovarlo? – Kissaki

+1

@Kissaki: mi sarei riferito a C++ 03, che non è legalmente disponibile online. Tuttavia, la formulazione è molto simile in C++ 11, una bozza del quale è disponibile su http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf –

+0

Ah, grazie .. – Kissaki

-2

se funziona, è un'estensione non standard.

delete [] array; 

è la forma corretta.

delete array; 

a volte funziona anche ma dipende dall'implementazione (quindi errata).

+1

Il comportamento del secondo modulo (senza parentesi) è chiaramente definito per i puntatori non di matrice. Il suo comportamento per gli array non lo è. Ad ogni modo, immagino sia questa la ragione per cui qualcuno ti ha votato. –

+1

'delete array' non" funziona "in alcun senso della parola, a meno che non si intenda che non si blocca il programma. Non recupererà tutta la memoria allocata in primo luogo, e se non si blocca, eseguirà solo il distruttore sul primo oggetto dell'array. (Che è anche un errore se hai fatto 'new Foo [0]'.) – Bill

+1

@Bill: Vorrei poter commentare i commenti negativi. La tua affermazione potrebbe essere vera a volte e altre volte potrebbe non esserlo. Vedi qui: http://stackoverflow.com/questions/1553382/1553407#1553407 e il mio commento qui: http://stackoverflow.com/questions/1553382/1553391#1553391 – sbi

4

Primo punto: non c'è quasi mai un buon motivo per utilizzare il modulo di forma di nuovo o di eliminazione per iniziare - utilizzare invece std :: vector (o qualche altro contenitore).

Secondo: indietro nell'era buia del C++, si doveva specificare la dimensione dell'array che si stava cancellando, quindi se si utilizzava x = new T[N], l'eliminazione corrispondente era delete [N] x. L'obbligo di specificare esplicitamente la dimensione è stato rimosso lungo, ma alcuni compilatori (in particolare quelli che si preoccupano della retrocompatibilità con codice antico) lo consentono comunque.

A meno che tu non abbia davvero bisogno di rimanere compatibile con un compilatore antico (uno di 20 anni circa) non dovresti usarlo. Poi di nuovo, a meno che non sia necessario rimanere compatibili con un compilatore così vecchio da non supportare alcun contenitore standard, non si dovrebbe usare la forma dell'array di new o delete in primo luogo. Semplicemente fermati!

+0

Grazie per la lezione di storia. Quindi, se dovessi passare una matrice dinamica di, ad esempio, fluttua, a una libreria di terze parti, quale sarebbe il modo giusto di farlo con i contenitori standard? – raven

+0

Usa un vettore. Quando è necessario passare l'indirizzo/lunghezza, utilizzare & vec [0] e vec.size(). –

+0

+1: nella bozza dello standard del '94 la sintassi era già 'cancella []'. E nello stesso anno, Design and Evolution (p218) ha commentato che questa sintassi "... si è dimostrata troppo soggetta a errori, quindi l'onere di tenere traccia del numero di elementi è stato invece posto sull'implementazione". –