I’m writing a Linked List in C
.
list.h
typedef struct list_struct * List; /* Defined in list.c */ List create_list(); void destroy_list(List list); void list_add(List list, void * item); void list_remove(List list, int is_target(void *)); ... /* Other handy functions like 'list_size', etc. */
list.c
typedef struct node_struct { void * item; struct node_struct * next; } * Node; typedef struct list_struct { Node head; ... /* Other handy things like size, tail, etc. */ } List; void list_remove(List list, int is_target(void *)) { ... /* Find target node to delete. */ free(target->item); ... /* Update links. */ free(target); } ... /* Other functions definitions. */
list_remove
: When removing a Node
(it’s used behind the scenes in list.c
), I need to obviously deallocate it (using free
). However, before freeing the Node
, should I also free the ‘item’ it contains?
My Take
Pro: The advantage to freeing the item so is that a client using this API would not have to keep track of the items he stores in a ‘list’. Plus, he wouldn’t have to worry about freeing the item himself.
Con: If the client wanted to use the item after deletion of the node, he can’t because it was destroyed. So, that’s why freeing the item could be a bad idea.
Solution: Change the function to void * list_remove(List list, int is_target(void *))
(note that it now returns void *
). It returns the item in the node (the node itself is destroyed). So, if the client does decide that he doesn’t need the item, he can just call free(list_remove(my_list, homework_that_dog_ate("HW 5")));
. And, if he wants to keep it, he can Homework dog_food = list_remove(my_list, homework_that_dog_ate("HW 5"));
.
Is my solution good? If not, where is it flawed? Is there a better approach?