2009-01-12 7 views
7

que tienen una estructura como esta:matriz de estructuras y nuevos/borrar

class Items 
{ 
private: 
    struct item 
    { 
     unsigned int a, b, c; 
    }; 
    item* items[MAX_ITEMS]; 
} 

Decir que quería 'eliminar' un elemento, así:

items[5] = NULL; 

Y he creado un nuevo elemento en ese mismo lugar más tarde:

items[5] = new item; 

¿todavía tenga que llamar delete[] a limpiar esto? ¿O no será necesario ya que se conocen los límites de la matriz items[] antes de compilar?

¿Está valiendo ese puntero a NULL o debería llamar a delete allí?

Respuesta

15

Debe llamar al delete antes de establecerlo en NULO. (No es necesario establecerlo en NULL, solo ayuda a reducir los errores si accidentalmente intenta desreferenciar el puntero después de eliminarlo).

Recuerde que cada vez que use new, necesitará usar más adelante en el mismo puntero. Nunca use uno sin el otro.

Además, new [] y delete [] van juntos de la misma manera, pero nunca se debe mezclar con new []delete o new con delete []. En su ejemplo, desde que creó el objeto con new (en lugar de new [] que crearía una matriz de objetos) debe eliminar el objeto con delete (en lugar de delete []).

0

C++ no es mi fuerte, pero estoy bastante seguro de que se estaría filtrando la memoria si establece el puntero a NULL.

EDITAR: La memoria que se está filtrando sería la memoria a la que apunta el puntero en la matriz.

0

Al configurar los elementos [5] en NULL no elimina la memoria asociada con el elemento, simplemente establece el puntero a ese elemento en NULO, por lo tanto, se pierde la memoria.

Puede eliminar el elemento llamando:

delete items[5]; 

Puesto que C++ no tiene recolección de basura automática, es necesario eliminar cualquier memoria que ya no necesite.

6

Como señaló Kluge, se perdería el objeto en el índice 5 así. Pero esta realmente suena como que no deberías hacer esto manualmente, pero usa una clase contenedor dentro de Item. Si realmente no necesita almacenar estos objetos item como punteros, use std::vector<item> en lugar de esa matriz de MAX_ITEMS punteros. Siempre puede insertar o borrar elementos vectoriales en el medio también si lo necesita.

En caso de que necesite para almacenar los objetos como punteros (por lo general si item estructura es en realidad polimorfa, al contrario que en el ejemplo), puede utilizar impulso :: ptr_vector < elemento de > Boost.PtrContainer lugar.

Ejemplo:

class Items { 
private: 
    struct item { 
     unsigned int a, b, c; 
    }; 
    std::vector<item> items; 
} 

if (items.size() > 5) // (just to ensure there is an element at that position) 
    items.erase(items.begin() + 5); // no need to use operator delete at all 
1

Para eliminar un uso del artículo:

eliminar elementos [5];

después de eliminar el elemento, es aconsejable establecer el puntero eliminado en NULO, por lo que no tendrá un error si lo elimina de nuevo por error.

artículos [5] = NULL

+0

Acepto esta respuesta – karthik

1

dicen que quería 'eliminar' un elemento, así:

artículos [5] = NULL;

Sé poco de Visual Basic, pero que huele a un lenguaje de programación Visual Basic, ya que "Set a = None" (o nulo, no estoy seguro) sería eliminar el objeto señalado por una (o más bien disminuir su recuento de referencia, para objetos COM).


Como más ha dicho alguien, usted debe utilizar:

delete items[5]; 
items[5] = newContent; 

o:

delete items[5]; 
items[5] = NULL; 

Después delete[5], el único uso posible del puntero almacenado en items[5] está causando problemas . Lo que es peor es que podría funcionar al principio y comenzar a fallar solo cuando se asigna algo más al espacio utilizado anteriormente por *items[5]. Esas son las causas que hacen que la programación C/C++ sea "interesante", es decir, realmente molesta (incluso para quien le gusta C me gusta).

Escribir solo delete items[5]; guarda lo que puede ser una escritura inútil, pero eso es una optimización prematura.

1

Para que quede claro: se refiere a la llamada "delete[]". Creo que te refieres al delete.

Menciono esto porque C++ tiene dos operadores separados, operator delete y operator delete[]. Este último se utiliza para eliminar matrices de objetos asignados con operator new[], y se aplica no en este caso. Tiene una matriz de punteros a objetos, que debe haber inicializado con llamadas repetidas al operator new en lugar de una sola llamada al operator new[].

Todo lo que estoy tratando de decir es: el uso de delete[] es confuso y ambiguo; cámbielo a delete.

1

Hay unos pocos, relacionados, preguntas aquí:

  1. De acuerdo con el código que envió, la matriz en sí no se asigna en el montón a menos que el struct es decir, por lo que no es necesario el delete[] formación. Si creó la matriz con new[], tendría que delete[].
  2. El código publicado no indica cómo se asignan los objetos que se apuntan desde la matriz. Si asigna esos objetos en la pila, no debe eliminarlos (de). De nuevo, esto es muy improbable porque sus punteros se volverán inválidos cuando los objetos que señalan caigan fuera del alcance. Si los asignó en el montón (con nuevo), entonces debe eliminarlos cuando se salgan del alcance.
  3. Como ya han sugerido otros, la vida es mucho más fácil si usa un contenedor (especialmente un contenedor STL) y punteros inteligentes, que por ahora significa punteros de Boost.
Cuestiones relacionadas