C语言 我的链表代码中有什么错误?



这是我用ANSI C编写的代码。 我经常收到运行时错误:分段错误(SIGSEGV(。 请帮帮我。 我是数据结构和 C 的新手。 我无法检测到问题。

#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *nxt;
}node;
node * create(int n);
void display(node *head);
int main()
{
int n = 0;
node *head = NULL;
printf("Enter the number of nodesn");
scanf("%d", &n);
head = create(n);
display(head);
return 0;
}
node * create(int n)
{
int i;
node *head = NULL;
node *temp = NULL;
node *p = NULL;
for (i = 0; i < n; i++)
{
temp = (node *)malloc(sizeof(node));
printf("nEnter the value of %d node", i + 1);
scanf("%d", &temp->data);
temp->nxt = NULL;
if (head == NULL)
{
head = temp;
}
else
{
p = head;
while (p->nxt != NULL)
{
p = p->nxt;
p->nxt = temp;
}
}
}
return head;
}
void display(node *head)
{
node *p = NULL;
if (head = NULL)
{
printf("nEmpty List");
}
else
{
p = head;
while (p != NULL);
{
printf("%d->", p->data);
p = p->nxt;
}
}
}

托马斯·雅格在他的答案中给出了一个重要的修复。 我在评论中给了你两个重要的修复。 当这些组合在一起时,代码对我有用。

#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *nxt;
} node;
node *create(int n);
void display(node *head);
static void error(const char *msg)
{
fprintf(stderr, "%sn", msg);
exit(EXIT_FAILURE);
}
int main(void)
{
int n = 0;
node *head = NULL;
printf("Enter the number of nodes: ");
if (scanf("%d", &n) != 1)
error("failed to read an integer");
head = create(n);
display(head);
return 0;
}
node *create(int n)
{
int i;
node *head = NULL;
node *temp = NULL;
node *p = NULL;
for (i = 0; i < n; i++)
{
temp = (node *)malloc(sizeof(node));
if (temp == NULL)
error("failed to allocate memory");
printf("nEnter the value of %d node: ", i + 1);
if (scanf("%d", &temp->data) != 1)
error("failed to read an integer");
temp->nxt = NULL;
if (head == NULL)
{
head = temp;
}
else
{
p = head;
while (p->nxt != NULL)
{
p = p->nxt;
}
p->nxt = temp;
}
display(head);   // Debugging - check the list as it is built
}
return head;
}
void display(node *head)
{
node *p = NULL;
if (head == NULL)
{
printf("Empty Listn");
}
else
{
p = head;
while (p != NULL)
{
printf("%d->", p->data);
p = p->nxt;
fflush(stdout);     // Band-aid - remove ASAP
}
putchar('n');
}
fflush(stdout);     // Band-aid - remove ASAP
}

我在输入代码中使用了display函数来确保列表始终干净地工作。 它占了下面显示的列表的额外副本。 该代码还使用换行符终止输出行,这有助于确保它显示。 有两个记录在案的"删除我"调用不需要fflush(stdout),但在代码崩溃时在调试时很有帮助。 有一个部分论点,即提示printf()调用后应跟一个fflush(stdout),以确保提示显示。 交互式输出通常不需要它。

请注意,我添加了一个错误报告函数,以便于报告错误,因此鼓励检测可能的错误。 您可以在 GitHub 上的 SOQ(堆栈溢出问题(存储库中看到我首选的错误处理代码,作为文件stderr.c并在 src/libsoq 子目录中stderr.h

当我使用数据结构(例如列表(时,我通常会为自己创建一个dump_list()函数。 通常有 2 或 3 个参数:

void dump_list(const char *tag, const node *list);
void dump_list(FILE *fp, const char *tag, const node *list);

"tag"参数用于注释输出:

dump_list(__func__, head);  // In create()
dump_list("result", head);  // In main()

标签很重要;它允许您为使用该函数的每个位置创建一个不同的标记(我使用了dump_list("point 1", …)dump_list("point 2", …),...在很多情况下在单个函数内(。 如果我认为我可能需要它转到标准输出以外的其他输出(例如标准错误或日志文件(,我会为自己提供带有FILE *参数的版本。 使用此功能可以检查数据结构。 请注意,不允许该函数修改数据结构。display()函数的格式可能与dump_list()函数不同,在这种情况下,您不会在main()函数中调用dump_list()。 但是,使用这样的函数来验证数据结构会有很大帮助。

使用显示的代码,我可以运行该程序(ll53ll53.c创建,使用 GCC 8.1 set fusy 干净地编译(,如下所示:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes 
>     -Wstrict-prototypes ll53.c -o ll53 
$ ./ll53
Enter the number of nodes: 1
Enter the value of 1 node: 234
234->
234->
$ ./ll53
Enter the number of nodes: 2 
Enter the value of 1 node: 234
234->
Enter the value of 2 node: 123
234->123->
234->123->
$ ./ll53
Enter the number of nodes: 7
Enter the value of 1 node: 987
987->
Enter the value of 2 node: 888
987->888->
Enter the value of 3 node: 789
987->888->789->
Enter the value of 4 node: 345
987->888->789->345->
Enter the value of 5 node: 444
987->888->789->345->444->
Enter the value of 6 node: 543
987->888->789->345->444->543->
Enter the value of 7 node: 0
987->888->789->345->444->543->0->
987->888->789->345->444->543->0->
$ ./ll53
Enter the number of nodes: 0
Empty List
$

在这一部分:

while(p->nxt!=NULL)
{
p=p->nxt;
p->nxt=temp;
}

我认为p->nxt=temp;应该在循环之外,如下所示:

while(p->nxt!=NULL)
{
p=p->nxt;
}
p->nxt=temp;

相关内容

  • 没有找到相关文章

最新更新