2010-02-15 23 views
12

¿Es este un destructor LinkedList válido? Todavía estoy un poco confundido por ellos.Escribiendo un destructor LinkedList?

Quiero asegurarme de que estoy entendiendo esto correctamente.

LinkedList::~LinkedList() 
{ 
    ListNode *ptr; 

    for (ptr = head; head; ptr = head) 
    { 
    head = head->next 
    delete ptr; 
    } 
} 

Así que al principio del bucle, puntero PTR se ajusta para mantener la dirección de la cabeza, el primer nodo de la lista. la cabeza se establece en el siguiente elemento, que se convertirá en el comienzo de la lista una vez que esta primera eliminación se lleve a cabo. ptr se elimina, y también lo es el primer nodo. Con la primera iteración del ciclo, el puntero se establece en cabeza nuevamente.

Lo que me preocupa es llegar al último nodo. La condición "cabeza" debería verificar que no sea nulo, pero no estoy seguro de si funcionará.

Cualquier ayuda apreciada.

+0

¿Por qué no intentas ejecutar el código a través de un depurador para ver si funciona? – Manuel

+0

@Manuel, porque los depuradores en ciertas plataformas no están integrados, y son difíciles de usar? –

+2

Sé que recibiré un disparo por esto (alguien siempre lo hace, pero yo soy un ganador). head es una variable miembro, realmente deberías tener una convención de nomenclatura para las variables miembro, como m_head o head_ – pm100

Respuesta

15

¿Por qué no hacerlo mucho más simple - con un elegante while -loop en lugar de tratar de analizar cuidadosamente si ese overcpilcated for -loop es correcto?

ListNode* current = head; 
while(current != 0) { 
    ListNode* next = current->next; 
    delete current; 
    current = next; 
} 
head = 0; 
+1

por supuesto, esto funcionará ... ¿pero si el código original mencionado por OP funcionará? – Naveen

+0

Debo comentar que 'current' nunca cambia y' next' nunca se usa. ¿Fue significado como un mal juego de palabras hacia el OP? –

+6

@Matthieu M .: No hay malos juegos de palabras previstos. ¿Podrían detallar "nunca cambia" y "nunca se usó"? – sharptooth

3

La condición "cabeza"; debería verificar que no sea nulo, pero no estoy seguro de si funcionará.

Sí, "cabeza" por sí mismo es lo mismo que "la cabeza! = Null" - pero ¿por qué utilizar un acceso directo a escribir sentido si incluso le resulta confuso? Son solo 6 teclas más (y genera un código de máquina idéntico), así que opta por la forma larga.

Además, su código es un poco más complicado de lo necesario porque está utilizando una construcción for(). ¿Por qué no usar un while()? Tu código será mucho más limpio.

Finalmente, me doy cuenta de que está haciendo esto como un ejercicio de aprendizaje, pero tenga en cuenta que la lista <> está en la biblioteca estándar --- Las listas vinculadas son oficiales un "Problema resuelto".

+0

Lo que quise decir es que, dado que la cabeza puede ser nula, ¿me encontraría con problemas para acceder al "próximo"? Por lo que entiendo, la cabeza apuntaría al último nodo, y el siguiente acceso contendría null en lugar de una dirección para el siguiente nodo. – kevin

5

Puede ejecutarlo a través de un depurador o puede ejecutarlo a través de ese poco de wetware dentro de su cráneo; ambos le mostrarán que funciona bien. Por ejemplo, vamos a empezar con la lista:

head(47) -> [47]single_node -> [NULL]end-of-list. 

Ejecución de esa lista a través de sus declaraciones:

  • ptr = head conjuntos ptr a 47.
  • head no es cero por lo que entrar en bucle.
  • head = head->next establece head en NULL.
  • delete ptr borrará el single_node.
  • ptr = head establece ptr en NULL.
  • head ahora es NULL (0) para salir del ciclo.

Ahí va, ha eliminado la única entrada en la lista y head ahora se establece en NULO. Eso es todo lo que necesitas hacer.

Puede hacer algo similar con una lista más larga o una lista vacía, encontrará que todavía está bien (no hay diferencia real entre una lista de un elemento y una lista de cincuenta elementos).

Dicho sea de paso, no soy un gran fan de tratamiento de punteros como booleanos - Prefiero escribir como algo así como:

for (ptr = head; head != NULL; ptr = head) 

Esto hace que el código de lectura mejor en mi opinión y usted don Realmente sacrifiques cualquier actuación (a menos que tengas un compilador cerebralmente muerto). Pero eso es una cuestión de gusto.

Re tu comentario:

Lo que me preocupa es llegar al último nodo. La condición "cabeza" debería verificar que no sea nulo, pero no estoy seguro de si funcionará.

Funcionará. Un valor de cero se tratará como falso, por lo que encontrará que nunca desreferencia cabeza-> siguiente cuando la cabeza es NULL simplemente porque habrá salido del cuerpo del bucle antes de ese punto (o incluso no ingresó el cuerpo si la lista está vacía)

Cualquier otro valor de puntero se tratará como verdadero y usted ingresará o continuará el cuerpo del bucle.

0

Tu código puede ser correcto, debes intentarlo con, p. Valgrind y mira lo que dice. Sin embargo, me gustaría escribir así:

for (ListNode *current = head, *next; current; current = next) { 
    next = current->next; 
    free(current); 
} 
1

probó muy bien

destructor para la clase Lista

List::~List() 
{ 
    Node *n = this->front, *current = NULL; //initialization part 

    while(n)        //start cleanup of nodes of the list 
    { 
     current = n; 
     n=n->next; 
     delete(current); 
    } 

    front = end = NULL; 
} 
0

Ésta es una mejor aproximación para liberar/borrado de la memoria utilizando destructor de un Linked -Lista.

List()::~List() 
      { 
       for(Link* ptr= Head; Head; Head= Head->next) 
       { 
        delete ptr; 
       } 
      }