0

LINKED LISTS IN C

Suppose I have a simple List and already insert several Nodes. Which of these options to Free Memory is the correct 1 or 2? He always told me not to touch the node * head

#include <stdio.h>
#include <stdlib.h>

typedef struct _Nodo{
  int dato;
  struct _Nodo *siguiente;

}Nodo;

//Prototipos
void LiberarNodos( Nodo *cabeza);


int main(){
  Nodo *cabeza=NULL;


return 0;
}




//OPCION 1
void LiberarNodos( Nodo *cabeza){
        Nodo *test;
        test=cabeza;
        while( test !=NULL){
            free(test);
            test=test->siguiente;
         }
        }


//OPCION 2
void LiberarNodos( Nodo *cabeza){
        Nodo *test;

        while( cabeza !=NULL){
            test=cabeza;
            cabeza=cabeza->siguiente;
            free(test);
         }
        }

In Option 1 : it is proposed by me, but I have not seen it in any tutorial
In Option 2 : If it appears in some but it seems that it does not release the First Node, it starts with the Second Node.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 1
    You should adjust the pointers in the list before calling free, if you call free before you've finished with the pointer then you will corrupt memory. Option 1, save test to another, reassign, then free saved pointer. – SPlatten Nov 26 '19 at 07:44
  • 2
    Option 1 is plain wrong. Dereferencing a pointer once it has bee freen leads tol undefined behaviour which includes "apparently working fine".. – Jabberwocky Nov 26 '19 at 07:45
  • From your explanation, I gather you don't understand why option 2 is correct ? It does not "start with the Second Node" as you think. I recommend drawing it out while following the code. Also, refer to this question for an explanation : [C: How to free nodes in the linked list?](https://stackoverflow.com/questions/6417158/c-how-to-free-nodes-in-the-linked-list). – Sander De Dycker Nov 26 '19 at 07:51

2 Answers2

1

Option 2 seems ok. Option 1 frees memory and then tries to access it, which is wrong.

nivpeled
  • 1,810
  • 5
  • 17
0

The first function implementation is wrong because there is an attempt to access already deallocated memory

        free(test);
        test=test->siguiente;

So the function has undefined behavior.

But the both functions have the same drawback. The passed to the function head node is not changed in the function because it is passed by value. So after exiting the function the head node will not be equal to NULL. If the user of the list forgets to set the ;pointer to NULL "manually" then this can result in using the pointer as if the list was not freed.

A better approach is pass the head node to the function by reference. For example

void LiberarNodos( Nodo **cabeza )
{
    while( *cabeza != NULL )
    {
        Nodo *tmp = *cabeza;
        *cabeza = ( *cabeza )->siguiente;
        free( tmp );
    }
}

In this case after exiting the function the head node will be equal to NULL. That makes the program more safer.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335