C语言 链表进行分割错误



下面我用C做了一个简单的链表。该代码当前正在产生一个分段错误,我觉得这很奇怪,因为我正在从我们当前的书中复制一个例子。我对代码所做的唯一一件事就是将代码放入方法"addToList"中。我知道分割错误来自方法addToList,但我不知道我在哪里犯了错误。

#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node *next;
} Node;
void addToList(Node *, int);
void printList(Node *);
void main() {
int x;
Node *head = malloc(sizeof(Node));
for (x = 1; x < 4); x++) {
printf("Enter an integer: ");
x = scanf("%d");
addToList(head, x);
}
printList(head);
}
void addToList(Node *head, int val) {
Node *current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = malloc(sizeof(Node));
current->next->val = val;
current->next->next = NULL;
}
void printList(Node *head) {
Node *current = head;
while (current != NULL) {
printf("%d->", current->val);
current = current->next;
}
printf("n");
}

任何帮助告诉我出了什么问题或我在哪里犯了错误将不胜感激。

仔细查看您的代码:

int main(void) {
int x;
Node *head = malloc(sizeof(Node));
for (x = 1; x < 4); x++) {
...
addToList(head, x);
}
...
}

您没有初始化内存,因此head->valhead->next不是 初始 化。正因为如此

while (current->next != NULL) {
current = current->next;
}

将循环未定义的次数。第一个current->next最 可能不是NULL,所以current = current->next被处决。在这一点上,current指向无处可去,因此在您的情况下会导致段错误而导致未定义的行为。

您必须像这样初始化内存:

Node *head = malloc(sizeof *head);
if(head == NULL)
// error handling
head->next = NULL;

但是您也可以使用calloc,它也将内存设置为 0,因此您不必初始化值(在本例中):

Node *head = calloc(1, sizeof *head);
if(head == NULL)
// error handling

您应该始终检查返回值malloc/calloc/realloc

另请注意,main函数的签名可以是以下之一:

  • int main(void);
  • int main(int argc, char **argv);
  • int main(int argc, char *argv[]);

编辑

我现在注意到的另一个错误:

x = scanf("%d");

这不是scanf的工作方式。你必须传递一个指针,scanf保存 通过传递的指针扫描值。scanf返回匹配的数量 成功的值,在本例中,成功将为 1:

int num;
int ret = scanf("%d", &num);
if(ret != 1)
{
fprintf(stderr, "Could not read value from the usern");
continue; // to contiune looping
// you could also do a break; and stop the looping, or
// exit(1), etc.
}
// error with scanf

也不要将相同的变量x用于循环迭代和用户输入, 否则你就会弄乱循环。

编辑

用户user3629249在评论中写道

很好的信息,但是结果将是链表中的第一个条目将包含垃圾。 最好通过以下方式声明头部:Node *head = NULL;和函数addToList()检查 NULL 并相应地继续。

没错,head元素不会以这种方式保存任何数字。

选项 1:双指针

在这里,addToList收到一个双指针。发生head的初始化 当*head指向NULL.该函数为其分配内存,初始化 内存,保存值并返回。在addToList的并发呼叫中*head不会NULL,所以addToList寻找列表的末尾。

我对你做mallocrealloc的方式做了一些小的改变。我还添加了 应该用于释放内存的freeList的实现:

void addToList(Node **head, int val) {
if(head == NULL)
{
fprintf(stderr, "head cannot be NULLn");
return;
}

if(*head == NULL)
{
*head = calloc(1, sizeof **head);
head[0]->val = val;
head[0]->next = NULL;
return;
}
Node *current = *head;
while (current->next != NULL) {
current = current->next;
}
current->next = malloc(sizeof *current->next);
if(current->next == NULL)
return;
current->next->val = val;
current->next->next = NULL;
}
int main(void)
{
int x;
Node *head = NULL;
for (x = 1; x < 4; x++)
{
int val;
printf("Enter an integer: ");
if(scanf("%d", &val) != 1)
{
fprintf(stderr, "Could not read from user. Skipping entryn");
continue;
}
addToList(&head, val);
}
printList(head);
freeList(head);
return 0;
}
void freeList(Node *head)
{
if(head == NULL)
return;
Node *current = head;
Node *next;
while(next = current->next)
{
free(current);
current = next;
}
free(current); // the last one
free(head);
}

选项 2:addToList返回指向头部的指针

在这里,addToList将指针指向头部。如果NULL,则分配 内存并初始化,如上所示。如果未NULLhead,则 函数查找最后一个元素并返回head。出错时 函数返回NULL

Node *addToList(Node *head, int val) {
if(head == NULL)
{
head = calloc(1, sizeof **head);
head->val = val;
head->next = NULL;
return head;
}
Node *current = *head;
while (current->next != NULL) {
current = current->next;
}
current->next = malloc(sizeof *current->next);
if(current->next == NULL)
return NULL;
current->next->val = val;
current->next->next = NULL;
return head;
}
int main(void)
{
int x;
Node *head = NULL, *tmp;
for (x = 1; x < 4; x++)
{
int val;
printf("Enter an integer: ");
if(scanf("%d", &val) != 1)
{
fprintf(stderr, "Could not read from user. Skipping entryn");
continue;
}
tmp = addToList(head, val);
if(tmp == NULL)
{
fprintf(stderr, "Not enough memoryn");
freeList(head);
return 1;
}
head = tmp;
}
printList(head);
freeList(head);
return 0;
}

相关内容

  • 没有找到相关文章

最新更新