链表节点释放数据的职责应该如何确定?
How should I decide the responsibility of freeing data in nodes of linked list?
单链表的C代码如下,
struct singly_linked_node {
void *data;
struct singly_linked_node *next;
}
struct singly_linked_list {
struct singly_linked_node *head;
}
struct singly_linked_list * singly_linked_list_malloc() {
struct singly_linked_list *list = malloc(sizeof(struct singly_linked_list));
if (list == NULL) {
return NULL;
}
list->head = NULL;
return list;
}
// inserts specified data specified index
// by adding a (internally initialized) new node
// and returns EXIT_(SUCCESS|FAILURE)
int singly_linked_list_insert(struct singly_linked_list *list, size_t index, void *data);
// deletes the node at specified index
// and returns the data of the deleted(freed) node
void* singly_linked_list_delete(struct singly_linked_list *list, size_t index);
如您所见,我试图让呼叫者只关注 ..._list
而不是 ..._node
。
我需要写一个函数释放singly_linked_list
的指针。
void singly_linked_list_free(struct singly_linked_list *list) {
assert(list != NULL);
// what about nodes in the list?
// what about data in each node?
free(list);
}
我应该 free(list)
吗?
我至少应该释放列表中的所有节点吗?
void singly_linked_list_free(struct singly_linked_list *list) {
assert(list != NULL);
for (struct singly_linked_node *i = list->head; i != NULL; i = i->next) {
void *data = i->data; // responsibility?
free(i);
}
free(list);
}
或者我是否应该释放所有数据指针?
void singly_linked_list_free(struct singly_linked_list *list) {
assert(list != NULL);
for (struct singly_linked_node *i = list->head; i != NULL; i = i->next) {
free(i->data);
free(i);
}
free(list);
}
如评论中所述,您负责节点和列表本身,但不负责数据,因为您无法知道(在任何情况下)数据是驻留在堆上还是堆栈上。
像这样简单地创建一个 foreach 方法:
void singly_linked_list_foreach (
struct singly_linked_list *list,
void (*callback)(void*)
){
//for every node in the list
//call 'callback' with the data as parameter, e.g.
//callback(item->data);
}
然后,如果您想释放列表中的所有数据:
singly_linked_list_foreach(list, free);
为了更舒适,重新声明您的 list_free 函数,例如:
void singly_linked_list_free (
struct singly_linked_list *list,
int free_data
){
if (free_data)
singly_linked_list_foreach(list, free);
//free all nodes
//free list
}
单链表的C代码如下,
struct singly_linked_node {
void *data;
struct singly_linked_node *next;
}
struct singly_linked_list {
struct singly_linked_node *head;
}
struct singly_linked_list * singly_linked_list_malloc() {
struct singly_linked_list *list = malloc(sizeof(struct singly_linked_list));
if (list == NULL) {
return NULL;
}
list->head = NULL;
return list;
}
// inserts specified data specified index
// by adding a (internally initialized) new node
// and returns EXIT_(SUCCESS|FAILURE)
int singly_linked_list_insert(struct singly_linked_list *list, size_t index, void *data);
// deletes the node at specified index
// and returns the data of the deleted(freed) node
void* singly_linked_list_delete(struct singly_linked_list *list, size_t index);
如您所见,我试图让呼叫者只关注 ..._list
而不是 ..._node
。
我需要写一个函数释放singly_linked_list
的指针。
void singly_linked_list_free(struct singly_linked_list *list) {
assert(list != NULL);
// what about nodes in the list?
// what about data in each node?
free(list);
}
我应该 free(list)
吗?
我至少应该释放列表中的所有节点吗?
void singly_linked_list_free(struct singly_linked_list *list) {
assert(list != NULL);
for (struct singly_linked_node *i = list->head; i != NULL; i = i->next) {
void *data = i->data; // responsibility?
free(i);
}
free(list);
}
或者我是否应该释放所有数据指针?
void singly_linked_list_free(struct singly_linked_list *list) {
assert(list != NULL);
for (struct singly_linked_node *i = list->head; i != NULL; i = i->next) {
free(i->data);
free(i);
}
free(list);
}
如评论中所述,您负责节点和列表本身,但不负责数据,因为您无法知道(在任何情况下)数据是驻留在堆上还是堆栈上。
像这样简单地创建一个 foreach 方法:
void singly_linked_list_foreach (
struct singly_linked_list *list,
void (*callback)(void*)
){
//for every node in the list
//call 'callback' with the data as parameter, e.g.
//callback(item->data);
}
然后,如果您想释放列表中的所有数据:
singly_linked_list_foreach(list, free);
为了更舒适,重新声明您的 list_free 函数,例如:
void singly_linked_list_free (
struct singly_linked_list *list,
int free_data
){
if (free_data)
singly_linked_list_foreach(list, free);
//free all nodes
//free list
}