Reputation: 63
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
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
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