Reputation: 1632
I just started studying linked list, and I tried to paint to understand it, and most of it I did, but I tackled with something strange, here's the piece of code I didn't understand:
If the allocation memory failed, what does this code do? and why do I need it? Can't I just free(temp)
and that's it?
while(Head!=NULL)
{
temp=Head;
Head=Head->next;
free(temp);
}
Here's the complete code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct Worker
{
int id;
char name[21];
struct Worker *next;
};
#define NUM 10
void main()
{
int i, id_to_del;
struct Worker *temp, *prev;
struct Worker *Head = NULL;
printf("Enter %d worker details:\n", NUM);
for (i = 0; i < NUM; i++)
{
temp = (struct Worker *)malloc(sizeof(struct Worker));
if (temp == NULL)
{
printf("Error allocating memory for worker #%d!", i + 1);
while (Head != NULL)
{
temp = Head;
Head = Head->next;
free(temp);
}
exit(1);
}
printf("Worker #%d: ", i + 1);
scanf("%d", &temp->id);
gets(temp->name);
temp->next = Head;
Head = temp;
}
}
Upvotes: 0
Views: 130
Reputation: 180978
The code block frees each node in a linked list, one at a time. Each node has a pointer, named next
, to the subsequent node in the list -- this is what makes the aggregate a "linked list". The syntax Head->next
means the same thing as (*Head).next
: it is the member named 'next' of the struct Worker
to which Head
, a pointer, points.
The code must use a temporary variable because once a block is freed, you can no longer dereference pointers to it -- for instance, to get the next
pointer that used to reside there. It tests for NULL
because this is how it recognizes that there are no more nodes; it gets the NULL
from either the original head node (in the case of an empty list) or from the next
pointer of the last node. It sets a new value for that temporary variable at every iteration of the loop. Note, too, that free()
does not free variables, pointers or otherwise; rather, it frees the dynamically-allocated memory to which pointers point. That makes the pointer's value useless, but it does not affect the pointer itself.
The nodes must be freed one at a time because that's the way dynamic allocation works. Each allocation must be matched with a separate free. And the free()
function cannot automated this in a case such as yours because
free()
function does not know any details about the contents of the block, such as which bytes constitute pointers,Upvotes: 0
Reputation: 2751
malloc()
does not signal the kernel to terminate execution of the current process of the code. Upon failure, malloc simply returns a NULL
pointer with no effect on the program flow. free
can never fail (for NULL
pointers) and free()
ing a NULL
pointer has no effect.
Added note:
In most cases, the cast is not needed for malloc
call in the current versions of C
Upvotes: 0
Reputation: 978
As user1320881 was saying, the piece of code runs though the list and deallocates it head first to last.
So A > B > C woud call free(A)
then free(B)
then free(C)
If a malloc
had failed that pointer would be set to NULL (Link: http://linux.die.net/man/3/malloc)
Freeing a NULL pointer has no effect.
EDIT:
Head-> next
you would expect to be the pointer to the next "worker".
So the outer loop (for(i=0; i<NUM; i++)...
) populates the fields for each worker, using user input. If there is an allocation failure it frees the entire list (would prevent memory leaks when the program continues) and exits the program (which is unnecessary when exiting to program, but still good practice in my opinion).
Upvotes: 1