我正在编写一个打印链表的小程序。此列表包含一个字符串和指向下一个节点的指针。
我将链表传递给添加新节点并填充数据字段的函数。
当我回到main函数并尝试打印列表内容时,我得到了分段错误错误,尽管从函数add_node我可以打印节点的内容。
我希望能够将列表和字符串传递给函数,并且该函数必须使用我传递的字符串将新节点添加到列表中。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
char filename[25];
struct node *next;
};
typedef struct node LISTNODE;
typedef LISTNODE *LISTNODEPTR;
void add_node(LISTNODEPTR *nFile, char *chaData);
int main (int argc, char *argv[])
{
LISTNODEPTR nFile = NULL;
printf("Printing list\n");
add_node(&nFile, "file.txt");
printf("%s\n", nFile->filename);
free(nFile);
return 0;
}
void add_node(LISTNODEPTR *nFile, char *chaData)
{
LISTNODEPTR head = *nFile;
LISTNODEPTR newNode;
newNode = (LISTNODEPTR) malloc(sizeof (struct node));
strcpy(newNode->filename, chaData);
printf("%s\n", newNode->filename);
newNode->next = head; //link next. newNode next points to head (beginning of the list). At this time (head & newNode)->2nd->3rd->NULL
head = newNode;
}
输出: 打印清单 file.txt的 分段错误
OS: Linux sisdvb02 2.6.35-28-server#49-Ubuntu SMP Tue Mar 1 14:55:37 UTC 2011 x86_64 GNU / Linux
编译器:gcc -Wall -o list list.c
答案 0 :(得分:2)
nFile
函数中的 add_node()
不会更改。它仍然指向NULL
,因为您尝试取消引用NULL
,就会出现分段违例错误。顺便说一句,使用Valgrind来帮助解决这些问题。
将您的功能更改为以下内容:
void add_node(LISTNODEPTR *nFile, char *chaData)
{
LISTNODEPTR head = nFile;
LISTNODEPTR newNode;
newNode = (LISTNODEPTR) malloc(sizeof (struct node));
strcpy(newNode->filename, chaData);
printf("%s\n", newNode->filename);
newNode->next = head; //link next. newNode next points to head (beginning of the list). At this time (head & newNode)->2nd->3rd->NULL
head = newNode;
nFile = head;
}
答案 1 :(得分:0)
你有一个指向null的指针。然后将其分配给另一个变量,以便该变量现在指向null。然后你分配内存并指向那个内存。这不会改变原始指针仍然指向null。
将函数中的最后一行更改为
*nFile = head;
如果您不希望缓冲区溢出错误更改为:
strncpy(newNode->filename, chaData, 25);
newNod->filename[24] = 0;
答案 2 :(得分:0)
在add_node()
内,修改head
变量,它只是本地变量。这不会影响nFile
中的main()
变量 - 当控件返回NULL
时,它仍为main()
,这就是您出现分段错误的原因。
add_node()
中的最后一行应为:
*nFile = newNode;
答案 3 :(得分:0)
最重要的是IMHO要学习如何调试这样的故障。使用gdb
来了解程序崩溃的位置以及程序状态是很方便的。
$ gcc -Wall -g test.c -o test
$ gdb ./test
...
(gdb) run
...
Program received signal SIGSEGV, Segmentation fault.
...
(gdb) bt
#0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:32
#1 0x00007ffff7aa783c in _IO_puts (str=0x0) at ioputs.c:37
#2 0x0000000000400612 in main (argc=1, argv=0x7fffffffe6a8) at test.c:24
(gdb) frame 2
#2 0x0000000000400612 in main (argc=1, argv=0x7fffffffe6a8) at test.c:24
24 printf("%s\n", nFile->filename);
(gdb) print nFile
$1 = (LISTNODEPTR) 0x0
bt
给了我回溯,告诉我程序在崩溃时的确切位置。我从print nFile
知道nFile
仍然是NULL。为什么?好吧,你可以看到你将head = newNode
设置为add_node
的最后一行(分配给即将丢弃的临时变量),我假设你打算设置*nfile = newNode
(改为通过指针指定调用者的变量)。