The obvious answer is too obvious; so I'm going to assume you need a "less obvious" answer. There are 2 things I can think of.
Freeing a whole linked list (not just one node)
You want to make sure you don't use memory after it's freed. For linked lists this means that you should not do this:
while(node != NULL) {
free(node);
node = node->next; // BUG
}
To avoid this problem you should use a temporary variable, like this:
while(node != NULL) {
temp = node->next;
free(node);
node = temp;
}
Freeing before exit
For most operating systems there are layers of memory management (heap, management of virtual pages and virtual address spaces, management of physical RAM). When you free memory from the heap (free()
) it doesn't necessarily de-allocate the underlying virtual memory or de-allocate the underlying physical memory - the underlying memory is often kept as allocated at lower levels to improve the performance of a future allocations from the heap.
When your program exits (or crashes), the OS has to clean up the resources it was using, including destroying/de-allocating the entire virtual address space your program was using and everything that it contained (including anything on the heap that you didn't free with free()
). Because this is done using a "wholesale" approach (not a "piecemeal" approach), and because it's done at a lower level (bypassing the overhead of heap management), and because it's done by the kernel itself (bypassing the cost of system calls and transitions across the barrier between user-space and kernel-space), and because it must happen anyway (regardless of whether you free()
or not); it can be significantly faster and just as effective to not bother freeing anything on the heap before your program exits.
The main reason to free()
memory before exit is to detect memory leaks - anything still allocated (after you try to free everything) is memory that your program lost track of. However, most people don't build these kinds of checks into their software, and if they do it's easy enough to make it optional (e.g. use an "#ifdef MEM_LEAK_TEST_AT_EXIT
" so it can be enabled during testing but disabled for release).