为什么链接列表中的追加功能不起作用?

问题描述 投票:-1回答:2

当程序想要将节点添加到链表时(在执行追加功能时),程序会有运行时错误。

我测试了'创建'和'前置'功能,他们正确地完成了他们的部分。

#include <stdio.h>
#include <stdlib.h>
struct Node {
    int data ;
    struct Node* next ;
};

struct Node* Head=NULL ;

struct Node* create(int ,struct Node*);
struct Node* prepend(int ,struct Node*);
struct Node* traverse(struct Node*);
struct Node* append(int ,struct Node*);

int main()
{
    int data =4 , i ;
    Head = prepend(data,Head);
    for(i=0;i<3;i++){
        scanf("%d",&data);
        append(data,Head);
    }
    return 0;
}

创建用于添加新节点的func

 struct Node* create(int data ,struct Node* Head){
        struct Node* newNode = (struct Node*)malloc(sizeof(struct Node*));
        if(newNode == NULL){
            printf("Error\n");
            exit(0);
        }
        newNode -> data = data ;
        newNode -> next = Head ;
        return newNode ;
    }

在链表的第一个添加新节点:

struct Node* prepend(int data ,struct Node* Head){
        struct Node* newNode = create(data,Head);
        Head = newNode ;
        return Head ;
    }

用于返回上次创建的节点:

struct Node* traverse(struct Node* Head){
    struct Node* cursor = Head ;
    while(cursor->next != NULL || cursor->next != Head){
        cursor = cursor->next ;
    }
    return cursor ;
}

用于将新节点添加到链接列表的末尾:

struct Node* append(int data ,struct Node* Head){
    struct Node* newNode = create(data,Head);
    struct Node* cursor = traverse(Head);
    cursor->next = newNode ;
    return newNode ;
}
c
2个回答
0
投票

改变这个:struct Node* newNode = (struct Node*)malloc(sizeof(struct Node*));

对此:struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

分段错误错误来自遍历函数和while条件。似乎NULL值不能用于比较,我现在想知道为什么!顺便改变这个功能,然后再试一次:

struct Node* traverse(struct Node* Head){
  struct Node* cursor = Head ;    
  while(cursor->next){
      if(cursor->next == Head)
          break;
      cursor = cursor->next ;
  }
  return cursor ;
}

1
投票

你没有分配足够的字节

   struct Node* newNode = (struct Node*)malloc(sizeof(struct Node*));

sizeof(struct Node *)是指针的大小,你的结构包含一个指针+另一个字段,因此这是未定义的行为。

一个正确的方法(在解除引用的指针上使用sizeof来获得正确的大小而不是强制转换malloc的返回值):

   struct Node* newNode = malloc(sizeof(*newNode));

第二个问题在你的traverse函数中。当你做cursor = cursor->next时,cursor可能是NULL,你在下一次迭代时会被测试cursor->next。只需迭代列表并记住最后一个非NULL节点(并放弃测试Head作为下一个元素,因为它是不可能的:

struct Node* traverse(struct Node* Head){
    struct Node* cursor = Head;
    struct Node* retval = cursor;
    while (cursor != NULL) {
        retval = cursor;
        cursor = cursor->next;
    }
    return retval;
}
© www.soinside.com 2019 - 2024. All rights reserved.