Jeffrey Hennen
Jeffrey Hennen

Reputation: 63

Memory Management C and free() of pointers

so I have some questions on how to do correct memory management.

Basically my question is, what happens when for example I take this code(shown below). Does this need to be freed to prevent memory leaks?

    void traverseLeftRight(struct node *head){

        current = head;

        if(current == NULL){

            printf("There are no nodes within the list\n");
        }

        while(1){

            if(current != NULL){

                printf("left to right output:           %d\n", current -> value);
                current = current -> next;
            }else{

                break;
            }
        }
    }

Also, would free(current) and current = NULL break the list if i were do it within the break section of the list. Also, would something like this just break the pointing variable and not effect the node that it corresponds to?

void traverseLeftRight(struct node *head){

    current = head;

    if(current == NULL){

        printf("There are no nodes within the list\n");
    }

    while(1){

        if(current != NULL){

            printf("left to right output:           %d\n", current -> value);
            current = current -> next;
        }else{

            free(current);
            current = NULL;
            break;
        }
    }
}

Upvotes: 0

Views: 97

Answers (2)

user3629249
user3629249

Reputation: 16540

here is your first code, corrected, so an empty list does not enter the 'while()' loop

void traverseLeftRight(struct node *head)
{

    current = head;

    if(current == NULL)
    { // then list empty
        printf("There are no nodes within the list\n");
    }

    while( current != NULL )
    { // then, another node to print
        printf("left to right output:           %d\n", current -> value);
        current = current->next;   // step to next node in list
    }
}

here is your second code, with comments

while(1)
{

    if(current != NULL)
    { // then, not at end of list
        printf("left to right output:           %d\n", current -> value);
        current = current->next;  // step to next entry in list
    }

    else
    { // else, current == NULL ,, I.E. past end of list

        free(current);    // nothing will happen because Current == NULL
        current = NULL;   // already NULL, so nothing will change
        break;            // exit the 'while()' loop
    }
}

proposed code that free's the linked list as it traverses it.

Note that the 'head' needs to be updated as the list is 'free'd

// note the 'pointer to pointer parameter, so 'head' can be modified
void traverseLeftRight(struct node **head)  
{
    if( *head == NULL)
    {  // then, list is empty
        printf("There are no nodes within the list\n");
    }

    while( *head != NULL)
    { // while another node to process
        struct node *temp = *head; // remember current node pointer
        printf("left to right output:           %d\n", current -> value);
        *head = (*head)->next;     // step to next node
        free( temp );              // eliminate current node
    }
}

Upvotes: 0

Norman Gray
Norman Gray

Reputation: 12514

I think you are confused about memory management.

In the examples you've shown, there's no need for any freeing, because nothing has (as far as we can see) been allocated.

If you allocate memory with malloc(3) or friends, then you will typically need to free it later, exactly once. In general, failing to free something leaks memory (ie, the memory is still allocated, but you're not pointing to it any more, so can't use it), and freeing more than once is an error (in the sense that this opens the possibility of two bits of the code both believing they've been allocated exclusive use of the same bit of memory). Using a bit of memory (ie, dereferencing a pointer) after it's been freed is the classic ‘use-after-free’ error. Each of these results in somewhat hard-to-find bugs (but valgrind is your friend).

The call to free in your second would (unfortunately) not cause an error, because free doesn't report such errors.

You don't need to free memory if it's in use all the way to the end of the program – that's (in effect) freed automatically when the program finishes.

Almost the only case where you'd call free within a function like this is if you were writing a function to walk along a linked list (or something like that), freeing as it went. A traverse of a list (as your function name suggests) would not be expected to result in the list being freed.

Upvotes: 2

Related Questions