列出双链列表项C

问题描述 投票:0回答:1

我对C不熟悉。我正在尝试创建一个双向链接列表,其中数据字段是一个结构。但是当我输出元素时,仅正确显示结构的第一个字段。

struct n
{
    int a;
    int b;

};

typedef struct _Node {
    struct n *value;
    struct _Node *next;
    struct _Node *prev;
} Node;


typedef struct _DblLinkedList {
    size_t size;
    Node *head;
    Node *tail;
} DblLinkedList;


DblLinkedList* createDblLinkedList() {
    DblLinkedList *tmp = (DblLinkedList*) malloc(sizeof(DblLinkedList));
    tmp->size = 0;
    tmp->head = tmp->tail = NULL;
    return tmp;
}

void pushBack(DblLinkedList *list, struct n *value) {
    Node *tmp = (Node*) malloc(sizeof(Node));
    if (tmp == NULL) {
        exit(3);
    }
    tmp->value = value;
    tmp->next = NULL;
    tmp->prev = list->tail;
    if (list->tail) {
        list->tail->next = tmp;
    }
    list->tail = tmp;

    if (list->head == NULL) {
        list->head = tmp;
    }
    list->size++;
}
void printInt(struct n *value) {
    printf("%d, %d", value->a, value->b);
}
void printDblLinkedList(DblLinkedList *list, void (*fun)(struct n*)) {
    Node *tmp = list->head;
    while (tmp) {
        fun(tmp->value);
        tmp = tmp->next;
        printf("\n");
    }
}

所以,我有几个问题。我是否正确声明了节点值字段?我是否将节点正确插入列表的末尾?我是否正确地执行了双向链接列表项的输出?我的错误在哪里以及如何解决?

c struct linked-list doubly-linked-list
1个回答
1
投票

我是否正确声明了节点值字段?

这取决于您的意图。就存储指向struct n的指针而言:是。

我是否将节点正确插入列表的末尾?

我是否正确地输出了双向链表项目?

我的错误在哪里以及如何解决?

从我的角度来看,该代码有效,但是可能会误导pushBack的工作方式。 pushBackstruct n指针保持原样并将其存储在Node中。您没有发布pushBack调用者代码,但是如果调用者认为struct n被复制,则当前实现可能会导致问题。

为了说明这一点,请考虑以下因素:

  struct n value;
  value.a = 1;
  value.b = 2;
  pushBack(list, &value);
  value.a = 3;
  value.b = 4;
  pushBack(list, &value);

通过重用该值,两个链接列表节点将有效地包含相同的值。同样,插入的struct n指针必须在列表的整个生命周期内保持有效。因此,插入堆栈分配的值(稍后将通过离开其作用域而被释放)或过早释放动态分配的值可能会导致错误的值。只要呼叫者知道,这不一定是问题。

通常有三种处理内存所有权的方法:

  1. 数据结构拥有值(就像它拥有节点一样,并负责释放它们)
  2. 数据结构复制值并负责释放它们
  3. 呼叫者拥有价值并负责释放价值

对于链接列表,策略#3有很多优点,因为可以从现有值创建链接列表,而无需任何复制或所有权转移,这肯定会需要更改现有代码。这基本上就是您的代码目前正在执行的操作。

© www.soinside.com 2019 - 2024. All rights reserved.