如何释放链表中的信息?
How can I free information in a linked list?
我有一个包含 *head
和 **ptail
的双向链表。我编写了添加到列表和从列表中删除的代码,但我的问题是释放信息。
这是我的节点和链表的声明:
struct tcb_t { //Node
int thread_id;
int thread_priority;
ucontext_t *thread_context;
struct tcb_t *next;
}; typedef struct tcb_t tcb_t;
struct queue_t { //Linked List
tcb_t *head, **ptail;
}; typedef struct queue_t queue_t;
这是我初始化双向链表的代码:
struct queue_t* queue_create() { //Good
struct queue_t *q = (queue_t *) calloc(1,sizeof(queue_t));
q->head = NULL;
q->ptail = &q->head; // problem
return q;
}
我的问题源于以下函数。此函数旨在释放列表中的所有节点,但 while 循环是无限的。我认为这是由于链表创建时尾部指向头部,但我不确定是否有办法在不重写 queue_create()
.
的情况下修复它
void t_shutdown() { //Fix
if(ready != NULL){
tcb_t *helper = ready->head;
while(helper->next != NULL){
tcb_t *temp = helper;
helper = helper->next;
if(temp->thread_id > 0){
free(temp->thread_context->uc_stack.ss_sp);
}
free(temp->thread_context);
free(temp);
}
free(ready);
}
ready = NULL;
}
我想遍历列表并释放所有数据,但 helper->next
永远是 NULL
。
如有任何帮助,我们将不胜感激。
编辑 1
这些函数展示了如何在列表中添加和删除数据:
void queue_add(struct queue_t *q, tcb_t *ptr) { //Good
*q->ptail = ptr;
q->ptail = &ptr->next;
}
tcb_t *queue_remove(struct queue_t *q) { //Good
struct tcb_t *ptr = q->head;
if (ptr) {
q->head = ptr->next;
if (q->ptail == &ptr->next) {
q->head == NULL;
q->ptail = &q->head; // problem
}
}
return ptr;
}
快速修复:
#include <stdlib.h>
typedef int ucontext_t;
typedef struct tcb_tag {
int thread_id;
int thread_priority;
ucontext_t *thread_context;
struct tcb_tag *prev;
struct tcb_tag *next;
} tcb_t;
typedef struct queue_tag {
tcb_t *head;
tcb_t *tail;
} queue_t;
queue_t queue_create()
{
queue_t queue = { NULL, NULL };
return queue;
}
void queue_add(queue_t *queue, tcb_t *node) // aka push_back()
{
if (queue->tail) {
queue->tail->next = node;
node->prev = queue->tail;
node->next = NULL; // just to make sure. Idk where those nodes come from.
}
queue->tail = node;
if (!queue->head)
queue->head = queue->tail;
}
tcb_t* queue_remove(queue_t *queue) // aka pop_front()
{
if (!queue->head)
return NULL;
tcb_t *old_head = queue->head;
queue->head = old_head->next;
if (queue->head)
queue->head->prev = NULL;
else queue->tail = NULL; // No head - no tail.
return old_head;
}
void t_shutdown(queue_t *queue)
{
for (tcb_t *curr_node = queue->head, *next_node; curr_node; curr_node = next_node) {
next_node = curr_node->next;
// do what you have to with curr_node->thread_context here
free(curr_node);
}
}
int main(void)
{
queue_t q = queue_create();
queue_add(&q, calloc(1, sizeof(tcb_t)));
queue_add(&q, calloc(1, sizeof(tcb_t)));
queue_add(&q, calloc(1, sizeof(tcb_t)));
queue_add(&q, calloc(1, sizeof(tcb_t)));
queue_add(&q, calloc(1, sizeof(tcb_t)));
queue_remove(&q);
queue_remove(&q);
queue_remove(&q);
t_shutdown(&q);
}
我有一个包含 *head
和 **ptail
的双向链表。我编写了添加到列表和从列表中删除的代码,但我的问题是释放信息。
这是我的节点和链表的声明:
struct tcb_t { //Node
int thread_id;
int thread_priority;
ucontext_t *thread_context;
struct tcb_t *next;
}; typedef struct tcb_t tcb_t;
struct queue_t { //Linked List
tcb_t *head, **ptail;
}; typedef struct queue_t queue_t;
这是我初始化双向链表的代码:
struct queue_t* queue_create() { //Good
struct queue_t *q = (queue_t *) calloc(1,sizeof(queue_t));
q->head = NULL;
q->ptail = &q->head; // problem
return q;
}
我的问题源于以下函数。此函数旨在释放列表中的所有节点,但 while 循环是无限的。我认为这是由于链表创建时尾部指向头部,但我不确定是否有办法在不重写 queue_create()
.
void t_shutdown() { //Fix
if(ready != NULL){
tcb_t *helper = ready->head;
while(helper->next != NULL){
tcb_t *temp = helper;
helper = helper->next;
if(temp->thread_id > 0){
free(temp->thread_context->uc_stack.ss_sp);
}
free(temp->thread_context);
free(temp);
}
free(ready);
}
ready = NULL;
}
我想遍历列表并释放所有数据,但 helper->next
永远是 NULL
。
如有任何帮助,我们将不胜感激。
编辑 1
这些函数展示了如何在列表中添加和删除数据:
void queue_add(struct queue_t *q, tcb_t *ptr) { //Good
*q->ptail = ptr;
q->ptail = &ptr->next;
}
tcb_t *queue_remove(struct queue_t *q) { //Good
struct tcb_t *ptr = q->head;
if (ptr) {
q->head = ptr->next;
if (q->ptail == &ptr->next) {
q->head == NULL;
q->ptail = &q->head; // problem
}
}
return ptr;
}
快速修复:
#include <stdlib.h>
typedef int ucontext_t;
typedef struct tcb_tag {
int thread_id;
int thread_priority;
ucontext_t *thread_context;
struct tcb_tag *prev;
struct tcb_tag *next;
} tcb_t;
typedef struct queue_tag {
tcb_t *head;
tcb_t *tail;
} queue_t;
queue_t queue_create()
{
queue_t queue = { NULL, NULL };
return queue;
}
void queue_add(queue_t *queue, tcb_t *node) // aka push_back()
{
if (queue->tail) {
queue->tail->next = node;
node->prev = queue->tail;
node->next = NULL; // just to make sure. Idk where those nodes come from.
}
queue->tail = node;
if (!queue->head)
queue->head = queue->tail;
}
tcb_t* queue_remove(queue_t *queue) // aka pop_front()
{
if (!queue->head)
return NULL;
tcb_t *old_head = queue->head;
queue->head = old_head->next;
if (queue->head)
queue->head->prev = NULL;
else queue->tail = NULL; // No head - no tail.
return old_head;
}
void t_shutdown(queue_t *queue)
{
for (tcb_t *curr_node = queue->head, *next_node; curr_node; curr_node = next_node) {
next_node = curr_node->next;
// do what you have to with curr_node->thread_context here
free(curr_node);
}
}
int main(void)
{
queue_t q = queue_create();
queue_add(&q, calloc(1, sizeof(tcb_t)));
queue_add(&q, calloc(1, sizeof(tcb_t)));
queue_add(&q, calloc(1, sizeof(tcb_t)));
queue_add(&q, calloc(1, sizeof(tcb_t)));
queue_add(&q, calloc(1, sizeof(tcb_t)));
queue_remove(&q);
queue_remove(&q);
queue_remove(&q);
t_shutdown(&q);
}