簡體   English   中英

C語言中的雙鏈表:為什么即使頭和尾沒有更改,我也必須顯式重新分配頭和尾?

[英]Doubly linked list in C: Why do I have to explicitly reassign head and tail even when they are not changed?

我有一個雙向鏈表,您可以在其中通過指向頭或尾節點的指針的指針添加到頭或尾。

這樣,您可以將頭和尾指針更新為最新的頭或尾節點的地址。

我有那些在其自己的函數中啟動並存儲在同時包含兩者的結構中的“指針指針”。

當我添加到尾巴或頭部時,必須顯式保存舊的頭部並重新分配,而尾巴則相反。 否則,結構會發生變異,並且頭部也變為尾部,或者尾部變為頭部。

我試圖了解發生了什么。 也許頭/尾巴保持結構必須靜態/全局定義?

資料來源:

#include <stdio.h>
#include <stdlib.h>

typedef struct dcl_node {
  char *content;
  struct dcl_node *next;
  struct dcl_node *prev;
} Node;

Node *create_node (char *content) {
  Node *n = malloc(sizeof(Node));
  n->content = content;
  n->next = NULL;
  n->prev = NULL;
  return n;
}

typedef struct dc_list {
  struct dcl_node **head;
  struct dcl_node **tail;
} DCList ;

DCList *init_list (char *content_head, char *content_tail) {
  Node *head = create_node(content_head);
  Node *tail = create_node(content_tail);
  head->next = tail;
  tail->prev = head;
  DCList *list = malloc(sizeof(DCList));
  list->head = &head;
  list->tail = &tail;
  return list;
}

void insert_head (char *content, DCList *list) {
  Node *old_head = *list->head;
  Node *old_tail = *list->tail; // note the saving here
  Node *node = create_node(content);
  node->next = old_head;
  old_head->prev = node;
  *list->head = node;
  *list->tail = old_tail; // and reassigning here
}

void insert_tail (char *content, DCList *list) {
  Node *old_head = *list->head; // note the saving here
  Node *old_tail = *list->tail;
  Node *node = create_node(content);
  node->prev = old_tail;
  old_tail->next = node;
  *list->head = old_head; // and reassigning here
  *list->tail = node;
}

int main (int argc, char *argv[]) {
  DCList *list = init_list("c", "d");

  insert_head("b", list);

  // If I don't explicitly save and reassign the tail node, 
  // in this case both head and tail would become the "b node".
    printf("head: %s\ntail: %s\n",
      (*list->head)->content, (*list->tail)->content);

  return 0;
}

因為list->headlist->tailinit_list函數中指向局部變量的指針。

init_list返回時,這些變量將被銷毀,並且可以重復使用存儲在其中的內存。

碰巧的是,當將它們保存在insert_headinsert_tail保存的headtail變量(可能是!)將獲得相同的內存地址,因此不會被覆蓋。 否則,舊的head可能會被node覆蓋。

這是一個大概的解釋-很難說出編譯器實際上在做什么。 但是關鍵是init_list返回時headtail被破壞,然后您的list->headlist->tail指向可以重用的空閑內存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM