Im working on a project in C and I am making a stack data structure. I want to know if I pop the first element if I can then free it just to avoid dealing with potential memory leaks if it doesn't get free'd later on.
struct node_s {
int a;
int b;
struct node_s *next;
}
struct list_s {
struct node_s *head;
size_t size;
}
typedef struct node_s *nodep_t;
typedef struct list_s *listp_t;
will something like this work?
struct node_s pop(listp_t list) {
struct node_s node = *(list->head);
nodep_t new_head = list->head->next;
free(list->head);
list->head = new_head;
return node;
}
If not I would just do it how I though originally and free the memory manually later on:
nodep_t pop(listp_t list) {
nodep_t node = list->head;
list->head = list->head->next;
return node;
}
CodePudding user response:
Both will work.
The latter, as you noted, requires the caller do the cleanup on the node in question once finished with it. Also, once fixed for error checking (you were going to fix that, right ?), it allows you to return a value to the caller that indicates error/empty state (e.g. NULL). The former does not allow that. In short, the first version has no way of telling the caller "bad pop". That is the reason most people deploy pop
mechanics that have no result returned, a top
access method to access the list front without removing it in the process, and an empty
method for checking if the list is empty. The trio of those three are typical, and provide the functionality you would need.
In both cases, however, the next
member of the "thing" being returned (assuming non-NULL in the latter case) should be cleared to NULL before the return is made, lest you have prying eyes peeking in to your container.