C中电路双链表的指针问题



底部的main中发生错误。

添加节点-数据:1
分段故障(核心转储)

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct Node
{
int data;
struct Node* prev;
struct Node* next;
}Node;
typedef struct List
{
Node* head;
Node* tail;
int count;
}List;
void InitList(List *list)
{
(list) = (List*)malloc(sizeof(List));
(list) -> head = NULL;
(list) -> tail = NULL;
(list) -> count = 0;
}
Node* CreateNode(int data)
{
Node* node = (Node*)malloc(sizeof(Node));
node -> data = data;
node -> prev = NULL;
node -> next = NULL;
return node;
}
void AddNode(List *list, Node* node)
{
if (!(list) || !node) return;
printf("Add Node - data : %dn", node -> data);
if ((list) -> count == 0)
{
(list) -> head = (list) -> tail = node;
node -> next = node -> prev = node;
}
else
{
node -> prev = (list) -> tail;
node -> next = node -> prev = node;

(list) -> tail -> next = node;
(list) -> head -> prev = node;
(list) -> tail = node;
}
(list) -> count++;
}
int main()
{
List list;
InitList(&list);
for (int i = 1; i < 5; i++) 
AddNode(&list, CreateNode(i));
return 0;
}

这是一个关于C中电路双链接列表的代码。存在原始代码,我对其进行了修改,以了解为什么使用原始多指针。在main中调用AddNode(&list, CreateNode(i)时直接发生错误。

(这里是原始代码的所在地,但不是英语)(https://huiyu.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EB%8F%99%EC%A0%81%ED%95%A0%EB%8B%B9%EC%9D%84-%EC%9A%A9%ED%9C-%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8链表-EA%B5%AC%ED%98%84)

我预计它会起作用,因为在main中,我声明了List list,然后调用了InitList(&list)。我以为这是引用调用,但可能不是

我试了一些测试,然后发现了一些问题。

  1. 我用列表类型list的地址调用InitList
  2. 我希望该列表会被初始化,因为我给出了带有地址的参数
  3. 但当我打印listcount的值时,它是垃圾值。(当我在InitList中打印时,那是0)
  4. 因此,当列表的headtailNULL(通过assert找到)时,count不为零,则发生错误

我无法理解为什么它不是通过引用调用,以及为什么需要多个指针。

请记住,函数的参数是通过值传递的。这意味着调用中的值被复制到函数的局部参数变量中。所有函数都有一个副本,它独立于调用中的原始变量或值。这意味着

(list) = (List*)malloc(sizeof(List));

在您的InitList中根本不起作用,您只能修改本地list变量。main函数中的原始值&list不会被修改。事实上,它不能。

这意味着您在InitList函数中初始化的List结构对象与main函数中的对象不同。main函数中的List结构对象将保持未初始化状态。

您似乎听说过,通过向变量传递指针来模拟逐引用传递。但您忽略了一个重要的点:指针本身仍将按值传递。

问题的简单解决方案是简单地从InitList函数中删除该赋值:

void InitList(List *list)
{
// list is already pointing to a properly allocated List structure
(list) -> head = NULL;
(list) -> tail = NULL;
(list) -> count = 0;
}

其他可选方案是将main函数中的list更改为指针,并将指针传递给该指针,这意味着InitList必须采用List **list参数或者您将list定义为一个普通的局部变量,进行分配,然后返回指针

当您编写列表时=>现在,当您在initlist()函数中再次执行malloc操作时,内存已经分配给了list对象,然后将指针指向一个新的内存位置,因此,以前指向list对象位置的指针现在指向其他地址位置。因此,您在initlist函数中对此指针所做的所有更改都会反映到存储在某个新地址位置(而不是列表对象)的结构对象中。

解决方案:与其他答案中提到的相同,即删除initlist函数中的malloc行。

或者您可以将malloc()留在InitList函数中,但您只需要将"list"变量定义为main()函数中list结构的指针:

List *list = NULL;

相关内容

  • 没有找到相关文章

最新更新