Autor Tema: Destrucción de lista en C

0 Usuarios y 1 Visitante están viendo este tema.

13 Febrero, 2014, 03:49 am
Leído 3483 veces

lul

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 126
  • Karma: +0/-0
  • Sexo: Femenino
Hola, soy principiante en C , estoy programando una lista y me piden que  realice una función para destruirla. El código que hice es el siguiente:
void eliminar(lista l){
int i;
posicionLista  p= l->header;
for (i=0; i<l->cantElementos; i++){
    free(p->elemento);  *(1)
    p->next;
}
free(l);       *(2)
}

en (1) libero la memoria para cada elemento y en 2 liberaría la lista. No estoy segura que esté bien y no se como verificarlo , porque en los ejemplos que he visto en la web dejan la lista vacia , pero sin realizar el free(2).
Gracias!

13 Febrero, 2014, 06:07 am
Respuesta #1

Autodidacta

  • $$\Large \color{#5372a0}\pi\,\pi$$
  • Mensajes: 65
  • Karma: +0/-0
  • Sexo: Masculino
No le veo mucho sentido a lo que hace ese código, quizás si pones como están definidas las estructuras que usas y como creas y añades elementos a la lista se pueda sacar algo en claro.

13 Febrero, 2014, 11:12 am
Respuesta #2

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,797
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
Si bien los ejemplos de los libros son siempre muy parecidos, y se puede inferir la estructura de tu lista, ocurre que está incompleto para quien lo lee.

Como bien apuntó Autodidacta, haría falta que pongas la definición de la estructura, para entender bien lo que estás haciendo.

La verdad es que así como está, no lo entiendo.

Saludos

13 Febrero, 2014, 04:56 pm
Respuesta #3

lul

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 126
  • Karma: +0/-0
  • Sexo: Femenino
Este es el código :

#define SIZE_ENTERO 10

//******************************definicion TDA*********************************************//
typedef struct
{
    char entero[SIZE_ENTERO];
    int cantDigitos;
} elargo;


typedef elargo* enteroLargo;


typedef struct n
{
    enteroLargo e;
    struct n* next;
} nodo;

typedef nodo* posicionEnteroLargo;

typedef struct l
{
    posicionEnteroLargo header;
    posicionEnteroLargo tail;
    int cantElementos;
} lista;

typedef lista* listaEnterosLargos;

//**********************************************************************************************//


enteroLargo crearEnteroLargo(void)
{
    return (enteroLargo) malloc(sizeof(elargo));
}

void setearEnteroLargo(enteroLargo unEntero, char numero[]){
 int i;
 int longitud = strlen(numero);
 unEntero->cantDigitos=longitud;
 for (i=0; i<=longitud; i++){
    unEntero->entero= numero;
 }

};



listaEnterosLargos crearLista(){
listaEnterosLargos l = malloc(sizeof(lista));

    l->header = NULL;
    l->tail = NULL;
    l->cantElementos = 0;

    return l;
}



posicionEnteroLargo agregarElemento(listaEnterosLargos l, enteroLargo el)
{
    posicionEnteroLargo nuevoNodo = malloc(sizeof(nodo));

    nuevoNodo->e = el;
    nuevoNodo->next = NULL;

    /* caso 1: lista sin elementos*/

    if (l->cantElementos == 0)
    {
        l->header = nuevoNodo;
        l->tail = nuevoNodo;
        l->cantElementos = 1;
    }
    else
    {/*agrega al final */
        l->tail->next = nuevoNodo;
        l->tail = nuevoNodo;
        l->cantElementos = l->cantElementos+ 1;
    }

    return nuevoNodo;
}


void eliminar(listaEnterosLargos l){
int i;
posicionEnteroLargo p= l->header;
for (i=0; i<l->cantElementos; i++){
    free(p->e);
    p->next;
}
free(l);
}

13 Febrero, 2014, 06:04 pm
Respuesta #4

Autodidacta

  • $$\Large \color{#5372a0}\pi\,\pi$$
  • Mensajes: 65
  • Karma: +0/-0
  • Sexo: Masculino
Estas liberando las estructuras de enteros , pero no los nodos de la lista, te falta hacer un "free(p);" dentro del bucle.

También tienes un "p->next;" que es una linea que no hace nada, tendría que ser "p= p->next;". Aun asi no bastaría con estos cambios, porque si liberas p, no puedes hacer un "p=p->next;" después, ya que "p" ya no existiría, tendrías que usar una variable extra para guardar el valor de "p->next" antes de liberar p.

Tampoco te haria falta usar una variable extra "i", ni la cantidad de elementos de la lista, ya que se puede recorrer la lista hasta que p->next sea igual a NULL. En realidad no se necesita guardar la cantidad de elementos de la lista en una variable, ya que la lista se puede manipular sin tener que usar ese valor.

Tampoco deberías usar typedefs para ocultar que estas usando punteros,  porque así no se sabe si una variable o un parámetro de una función se corresponde con un puntero o no, lo que hace que sea mas fácil de cometer errores, como por ejemplo dejar memoria sin liberar.
El código es mas difícil de entender de lo que debería, debido al uso de typedefs y los nombres que estas eligiendo para las variables y estructuras.

PD: Deberías poner el código entre las etiquetas correspondientes para que salga algo así:
Código: [Seleccionar]
/* ejemplo codigo */
Al no usar las etiquetas el código que has puesto sale modificado, por ejemplo lo que hay entre corchetes desaparece y da la impresión de que hay errores en algunas líneas (estoy suponiendo que no los hay y que algunos corchetes que faltan sí estan en el código original).

13 Febrero, 2014, 07:00 pm
Respuesta #5

lul

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 126
  • Karma: +0/-0
  • Sexo: Femenino
 perfecto, muchas gracias !

15 Febrero, 2014, 04:19 am
Respuesta #6

lul

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 126
  • Karma: +0/-0
  • Sexo: Femenino
otra pregunta, ahora estoy haciendo una función que debe crear una lista , resultado de unir dos listas pasadas por parámetro , eliminar los elemento repetidos  , y luego eliminar las listas, devolviendo la lista resultado sin los elementos repetidos.
Mi duda es la siguiente cuando creo la lista resultado, le copio la referencia de los nodos que no se repiten , para no tener que crear cada nodo con su elemento nuevamente, pero al finalizar no puedo eliminar las listas pasadas por parámetro porq se eliminan las referencias de los nodos , que usa la lista resultado; que otra solución podría ser?
 

15 Febrero, 2014, 09:06 am
Respuesta #7

Autodidacta

  • $$\Large \color{#5372a0}\pi\,\pi$$
  • Mensajes: 65
  • Karma: +0/-0
  • Sexo: Masculino
Haz una función que quite un nodo de una lista pero sin destruir el nodo, después simplemente quitas el nodo de una lista y lo añades a la otra.
Otra opción es primero unir las dos listas en una sola y después quitar los repetidos de la lista única que queda, así sólo tienes que eliminar nodos de la lista.

18 Febrero, 2014, 12:01 am
Respuesta #8

lul

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 126
  • Karma: +0/-0
  • Sexo: Femenino
Si uno las listas ; que hago con las otras listas tendria  q poner las referencias a header i tail  en NULL ? porq estaría usando los nodos a los que apuntan

18 Febrero, 2014, 09:15 am
Respuesta #9

Autodidacta

  • $$\Large \color{#5372a0}\pi\,\pi$$
  • Mensajes: 65
  • Karma: +0/-0
  • Sexo: Masculino
No, no necesitas poner nada a NULL. Puedes destruir simplemente esa estructura que no vas a usar más. Salvo que vayas a reutilizar esa estructura para crear otra lista en el futuro, en este caso sí te interesa poner todo a NULL así como la cantidad de elementos a cero para que conste que está vacía.
Los punteros solo guardan la dirección donde están los datos, no los datos en sí, no pasa nada porque tengas variables/punteros con esas direcciones, ya que la función free no es recursiva, no se pone a comprobar si hay punteros en la memoria que le pides que libere, para a su vez hacer un free de la memoria a la que hacen referencia esos punteros.