【发布时间】:2019-10-06 08:18:17
【问题描述】:
我有一个带有*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;
}
【问题讨论】:
-
您的节点不是双向链接的。为什么tail是指向指针的指针?为什么
queue_create()在堆上创建一个包含两个指针的结构? Don't cast the result of*alloc(). -
为什么是**ptail?你可能想把尾巴和头联系起来,但为什么不 q->ptail->next = q->head 呢?
-
@AnthonySette 那么请查看doubly-linked list 是什么。指向尾部的指针很好,但不足以使列表双向链接。
-
@AnthonySette 是的,您应该这样做,但请查看之前必须如何实现链表。
-
要进行双重链接,节点(例如
tcb_t)需要一个next[你有] 和一个prev[你没有有]。而且,队列应该有(例如)tcb_t *head和tcb_t *tail并且不是您当前拥有的(例如tcb_t **ptail)
标签: c linked-list free