2009-05-13 13 views
9

Quando ho compilato un codice utilizzando il nome dell'array come puntatore e ho cancellato il nome dell'array utilizzando delete, ho ricevuto un avvertimento sull'eliminazione di un array senza utilizzare il modulo dell'array (non ricordo il testo esatto).Qual è la forma dell'array di 'delete'?

Il codice di base era:

int data[5]; 
delete data; 

Allora, qual è la forma di matrice di eliminare?

+3

Che richiama il comportamento non definito poiché l'array non è stato allocato con nuovo []. –

risposta

33

La forma matrice di cancellazione è:

delete [] data; 

Edit: Ma, come altri hanno fatto notare, non si dovrebbe essere chiamata delete per i dati definiti in questo modo:

int data[5]; 

È dovrebbe chiamarlo solo quando si assegna la memoria utilizzando new in questo modo:

int *data = new int[5]; 
+2

Ma i suoi dati int [5] non sono stati assegnati dall'operatore new(), quindi non esiste una forma corretta di operator delete() che può essere chiamata. – RBerteig

+1

Interessante ... la risposta è corretta, ma oh così sbagliato. Come ha già ottenuto 17 voti? –

+2

È così facile rispondere alla domanda effettivamente posta, invece della domanda che avrebbe dovuto essere posta. Soprattutto quando è ripetuto sia nel titolo che nell'ultima frase. – RBerteig

0

Proprio come RichieHindle ha dichiarato sopra quando si desidera liberare lo spazio assegnato in modo dinamico per un array puntato da data, è necessario inserire due parentesi [] tra la parola riservata delete e il puntatore all'inizio dello spazio allocato. Poiché data può puntare a un singolo int in memoria e al primo elemento nell'array, questo è l'unico modo in cui si consente al compilatore di sapere che si desidera eliminare l'intero blocco di memoria. Se non lo fai correttamente, il comportamento è "indeterminato" (Stroustrup, The Language Programming C++).

2

Il codice come mostrato ha l'array nello stack o nella parte inizializzata del segmento di dati, ovvero non lo si disalloca (che, come menzionato da altri, sarebbe "comportamento indefinito".) nel "negozio gratuito" lo farei con delete [] data.

13

O si vuole:

int *data = new int[5]; 
... // time passes, stuff happens to data[] 
delete[] data; 

o

int data[5]; 
... // time passes, stuff happens to data[] 
// note no delete of data 

La regola generi è: applicabile solo delete alla memoria che veniva da new. Se è stata utilizzata la forma di matrice di new, è necessario utilizzare il modulo di matrice di delete per la corrispondenza. Se è stato utilizzato il posizionamento new, non chiamare mai delete o utilizzare un posizionamento corrispondente delete.

Poiché la variabile int data[5] è una matrice allocata staticamente, non può essere passata a nessuna forma dell'operatore delete.

3

Come l'altro hanno detto, è necessario utilizzare il modulo di vettore di cancellazione:

void some_func(size_t n) 
{ 
    int* data = new int[n]; 

    . . . // do stuff with the array 

    delete [] data; // Explicitly free memory 
} 

essere molto attenti a questo, perché alcuni compilatori non avvertire.

Ancora meglio, raramente c'è bisogno di usare il vettore nuovo/cancella.Considerare se il codice può essere modificato a fare uso di std :: vector:

void some_func(size_t n) 
{ 
    std::vector<int> data(n); 

    . . . // do stuff with the array 

} // memory held by data will be freed here automatically 

E se avete a che fare con la memoria in un ambito locale, è possibile utilizzare STLSoft s' auto_buffer, che assegnerà da un buffer interno (tenuto in pila, come parte dell'istanza), se possibile, solo andando al mucchio, se non ci riesce:

void some_func(size_t n) 
{ 
    stlsoft::auto_buffer<int, 10> data(n); // only allocates if n > 10 

    . . . // do stuff with the array 

} // memory held by data will be freed here automatically, if any was allocated 

more about auto_buffer Leggi.

Problemi correlati