打印链表数据时出现分段错误

时间:2013-01-17 19:23:20

标签: c

我正在编写一个打印链表的小程序。此列表包含一个字符串和指向下一个节点的指针。

我将链表传递给添加新节点并填充数据字段的函数。

当我回到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

4 个答案:

答案 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 (改为通过指针指定调用者的变量)。

相关问题