-2

I've a little confusion with structs and free operation in C. I have to use this struct ( I know is no best idea define *tList instead of tList but it must be that way)

    typedef struct cel{
    int elto;
    struct cel *bif;
    struct cel *next;
} *tList;

bif point to previus element, so y don't free() because i think its no necesary

Malloc tList list=(tList)malloc(sizeof(struct cel));

And later I need to free memory. I don't know what way is correct

call limpiar with list

 void limpiar (tList  borrar)
{
    tList aux;
    tList aBorrar;

    for(aBorrar = borrar; aBorrar != NULL; aBorrar = aux)
    {
        aux=aBorrar->next;
        free(aBorrar);
    }  
    return;
}

or

call limpiar with &list

void limpiar (tList  * borrar)
    {
        tList aux;
        tList aBorrar;

        for(aBorrar = *borrar; aBorrar != NULL; aBorrar = aux)
        {
            aux=aBorrar->next;
            free(aBorrar);
        }  
        return;
    }
user2835994
  • 3
  • 1
  • 6
  • You are using free correctly. But your code is probably wrong. Calling it with a pointer value that you did not get from malloc or doing double free. – typ1232 Mar 01 '15 at 16:26
  • `sig` is not a member of the struct in your example. did you forget to translate that part? what about `bif`? showing how you allocate memory for these structures is relevant. Both implementations of `limpiar` will do the same thing but the first is better/more common since the added indirection in the second does nothing accept allow the caller to let your code dereference NULL. – ryanpattison Mar 01 '15 at 16:31
  • sorry, i didnt translate. Now i think its correct and i add malloc. I didint understan this "the caller to let your code dereference NULL" – user2835994 Mar 01 '15 at 17:00
  • @rpattiso: OP is handling doubly linked lists, `bif` points to the previous cell, so it is not `free`d. OP is asking wether to pass the list head by reference or by value. – chqrlie Mar 01 '15 at 17:06
  • Refer these questions. This might help you! [malloc and free in C](http://stackoverflow.com/questions/28643691/malloc-and-free-in-c) and [Calling free( ) in C](http://stackoverflow.com/questions/14986543/calling-free-in-c) – Dushyanth Shenoy Mar 01 '15 at 17:08
  • @chqrlie it could have been an n-dimensional list, how would i know? – ryanpattison Mar 01 '15 at 17:14
  • @rpattiso: quoting the OP: *"bif point to previus element, so y don't free() "*. I agree the structure is similar to that of a binary tree, but it seems to be a doubly linked list here. I am assuming the list is not circular and the address passed to `limpiar` is that of the list head. More information and more code would help... – chqrlie Mar 01 '15 at 18:25
  • Yes @chqrlie thats correct, o didnt know if need extra indirection (second versión) to free correctly because of how arguments are pass – user2835994 Mar 01 '15 at 20:00

1 Answers1

0

If you pass the list by reference (second option), you will be able to clear the pointer to the list in the caller's data, or at least one of them. While it is not strictly necessary, not a perfect solution, it is good programming style and reduces the likelihood of referencing the cells after the free or calling free twice. The function should be modified this way:

void limpiar(tList *borrar)
{
    tList aux;
    tList aBorrar;

    for (aBorrar = *borrar; aBorrar != NULL; aBorrar = aux) {
        aux = aBorrar->next;
        free(aBorrar);
    }
    *borrar = NULL;
}

in the caller, you would invoke limpiar this way:

limpiar(&list);
// list is NULL now.
chqrlie
  • 131,814
  • 10
  • 121
  • 189