Linked lists of structures can grow considerably and use a lot of memory.
Calling free() is necessary. What I do now is to descend the list to the pointer
that points to the last node in the list and call free(structptr->nextnode), and travel backwards to free each preceeding node.
Would just freeing the pointer to the top of the list work just as well?
If you allocate a block of memory by calling malloc(), calloc() or
realloc(), and you don't call free() to deallocate that same block of
memory, then you have a memory leak. This applies separately to each
block - the memory allocation system doesn't know anything about the
fact that you've linked them together to form a list. If you allocated
each element of the list separately, then you have to free() each one
separately.
If you allocated a single block containing many different nodes, and
then linked them together to form a list, then you can deallocate that
entire block at one time - but calling free() on the head node will do
that only if the head node is also the first node in that block.
There's something called "garbage collection", which periodically checks
your entire memory to see if it contains anything that might be a
pointer into an allocated block of memory; if it finds no such pointers,
it automatically deallocates that block. A collector cannot, in general,
know the details of what memory means, so it can sometimes detect false
positives when a piece of memory that doesn't actually contain a pointer
happens to have the same bit pattern as a pointer to the allocated memory.
In effect, a garbage collection system DOES know about the fact that
your nodes are linked together. If you free the head node, sooner or
later it will notice that there's no pointers in memory pointing at the
second node of the list, and will collect it, too. Eventually, the
entire list will be collected. Note that this approach will not work on,
for instance, a doubly-linked list, because there are two pointers to
every node, and it cannot be deallocated until both have been collected
- therefore, none of them will be collected.
The malloc() family cannot use garbage collection, because the C
standard specifies that the life time of an allocated object continues
right up until it is explicitly free()d. There's no exception from this
requirement just because there are no pointers to that memory currently
in memory. Those pointers could be stored in an encrypted form not
recognized by the collector, or on disk, or they could even be displayed
for a user who writes them down and then types them back in later. If
there are no unencrypted copies of the pointer currently in memory,
garbage collection could collect the memory prematurely.
However, implementations can support garbage collection of memory
allocated by means other than the malloc() family. It's up to the user
of such memory to make sure that at least one pointer remains in memory
at all times, that points into any block of garbage-collectible memory
that the user doesn't want collected.