2011-01-12 21 views
30

Duplicar posibles:
delete vs delete[] operators in C++La diferencia entre eliminar y eliminar [] en C++

He escrito una clase que contiene dos punteros, uno es char* color_ y uno en vertexesset* vertex_ donde vertexesset es una clase que creé. En el destractor que he escrito en el arranque

delete [] color_; 
delete [] vertex_; 

cuando se trataba el destructor me dio un fallo de segmentación.

Entonces cambió el destructor a:

delete [] color_; 
delete vertex_; 

Y ahora funciona bien. ¿Cuál es la diferencia entre los dos?

+9

¿puede publicar el código donde asignó los dos punteros? es decir, la parte nueva. – clamp

+2

¿Seguiste la [Regla de los Tres] (http://stackoverflow.com/questions/4172722/)? – fredoverflow

+0

http://stackoverflow.com/questions/1553382/pod-freeing-memory-is-delete-equal-to-delete – sbi

Respuesta

53

Usted delete [] cuando new ed un tipo de matriz, y delete cuando no lo hizo. Ejemplos:

typedef int int_array[10]; 

int* a = new int; 
int* b = new int[10]; 
int* c = new int_array; 

delete a; 
delete[] b; 
delete[] c; // this is a must! even if the new-line didn't use []. 
+7

+1 para mencionar el caso con int_array. –

+0

+1, buena explicación! –

+2

Copiar del comentario a la otra respuesta: No es una buena idea usar los tipos de matriz, pero no es una mala idea mencionarlo, la gente se muerde. Además, el punto es que incluso cuando _escribes_ 'nuevo', a veces necesitas _escribir_' eliminar [] '. – etarion

5

Tiene que usar delete [] si asignó memoria en el montón con el operador new [] (por ejemplo, una matriz dinámica).

Si utilizó el operador nuevo, debe usar el operador delete, sin los corchetes.

No está relacionado con la eliminación de un tipo incorporado o una clase personalizada.

+0

No hace daño, sin embargo, utilizar delete [] en cualquier cosa creada con nuevo. El segfault debe tener otro motivo. – ypnos

+8

¿De dónde sacas la idea de que no duele? Está incorrecto. – etarion

+3

@ypnos: ¿En qué universo duele la conducta indefinida * no *? :) – fredoverflow

4

Cuando queremos liberar una memoria asignada a un puntero a un objeto y luego "eliminar" se utiliza.

int * p; 
p=new int; 

// now to free the memory 
delete p; 

Pero cuando hemos asignado la memoria de matriz de objetos como

int * p= new int[10]; //pointer to an array of 10 integer 

entonces a la memoria libre igual al 10 enteros:

delete []p; 

NOTA: Se puede liberar la memoria, incluso por delete p;, pero liberará solo la memoria del primer elemento.

+0

'new int (10)' asigna un solo 'int', no una matriz de 10' int'. –

+0

Hmm gracias por la corrección – Dotnet

1

Si tiene Effective C++ part 1 consulte el Artículo # 5: Use el mismo formulario en los usos correspondientes de nuevo y elimine.

+3

Y si no tiene C++ efectivo, ¡cómprelo ahora! – fredoverflow

12

delete y delete[] no son lo mismo! Wikipedia explains esto, si brevemente. En resumen, delete [] invoca el destructor en cada elemento en la matriz asignada, mientras que delete asume que tiene exactamente una instancia. Debe asignar matrices con new foo[] y eliminarlas con delete[]; para objetos comunes, use new y delete. El uso de delete[] en una matriz no puede causar estragos.

+0

Esta debería ser la respuesta, en realidad explica la diferencia. Gracias. – Andrew

+0

sí, esto perdió 40 votos a favor porque fue 2 minutos después. Es importante tener en cuenta que no puede usar delete [] como una solución general para manejar punteros sin formato. – jiggunjer

7
  • Si asigna con malloc(), se utiliza libre()
  • Si asigna la nueva utiliza eliminar
  • Si asigna la nueva [] se utiliza delete []
  • Si construir con ubicación-nuevo usted llama al destructor directo
  • Si tiene sentido usar vector en lugar de nuevo [] y luego usarlo
  • Si tiene sentido utilizar punteros inteligentes, utilícelos y no se moleste en llamar eliminar (pero igual deberás llamar a nuevo). La eliminación correspondiente estará en el puntero inteligente.

https://isocpp.org/wiki/faq/freestore-mgmt

+0

'Si asigna con new utiliza delete' - este no es siempre el caso, consulte mi respuesta. – etarion

+0

@etarion: No veo nada en su respuesta que contradiga esta afirmación; el uso de alias tipo alias invoca 'new []' not 'new', el alias de tipo simplemente ofusca ese hecho y probablemente sea una mala idea (¡incluso mencionarlo!). – Clifford

+1

No es una buena idea usar los tipos de matriz, pero no es una mala idea mencionarlo, la gente se muerde. Además, el punto es que incluso cuando _escribes_ 'nuevo', a veces necesitas _escribir_' eliminar [] '. – etarion

0

Y ahora funciona bien.

¿Más por suerte ese juicio si lo hace, y está seguro de que realmente está funcionando?

Se debe invocar el destructor para cada objeto, el operador delete[] usa la información establecida por new[] para determinar cuántos objetos destruir. Por lo tanto, aunque delete por sí solo puede recuperar la memoria (aunque si lo hace o no depende de la implementación), es posible que no llame al destructor para cada objeto asignado.

Es posible que la información sobre cómo se asignaron los objetos se incluya cuando se llaman new o new[] para que se use la forma correcta de eliminación independientemente, pero de nuevo depende de la implementación y no se garantiza.

0

además (obviamente mi velocidad de escritura debe mejorarse :), consideran no usar punteros si no lo hace realmente tiene que hacerlo. p.ej. char* se puede reemplazar por std::string, y si su miembro vertexesset no es polimórfico, puede convertirlo en un objeto miembro. En este caso, no necesitaría delete en total

Cuestiones relacionadas