c - 如何释放链接列表中的信息?

标签 c linked-list free

我有一个带有 *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);
}

关于c - 如何释放链接列表中的信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56212841/

相关文章:

c - 我调用 free(),但指针仍然有数据并且其内容没有改变

c - 调用 free() 时出现段错误

c - lseek 在 O_APPEND mod 中导致分段文件

c - 读取纺织品并添加到 C 中的链接列表

c++ - Stack中的无限循环,实现为 "Linked List"

java - 比较器不能为 Priorityqueue Java 正常工作

c - C 中的文件处理和图形 ADT

c - Unix 服务器客户端连接 : Connection refused

c++ - 代码 : How to address dynamic Variables?

c++ - 更改指针后,free() 将释放多少字节?