2

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

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

当我回到主函数并尝试打印列表内容时,我得到分段错误错误,尽管从函数 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;
}

输出:打印列表文件.txt 分段错误

操作系统: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

4 回答 4

3

nFile在你的add_node()功能没有改变。它仍然指向NULL并且由于您尝试取消引用 aNULL您会收到分段违规错误。顺便说一句,使用 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;
}
于 2013-01-17T19:27:15.380 回答
0

您有一个指向 null 的指针。然后将其分配给另一个变量,以便该变量现在指向 null。然后你分配内存并指向那个内存。这不会改变原始指针仍然指向空值。

将函数中的最后一行更改为

*nFile = head;

另外,如果您不想将缓冲区溢出错误更改为此:

strncpy(newNode->filename, chaData, 25);
newNod->filename[24] = 0;
于 2013-01-17T19:29:50.513 回答
0

在里面add_node(),你修改head变量,它只是局部变量。这不会影响nFile变量 in main()- 它仍然是NULL当控制返回时main(),这就是你得到分段错误的原因。

最后一行add_node()应该是:

     *nFile = newNode;
于 2013-01-17T19:31:04.317 回答
0

恕我直言,最重要的是学习如何调试这样的故障。使用它可以很方便地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 nFilenFile仍然是NULL。为什么?好吧,您可以看到您正在设置head = newNodeadd_node(分配给即将被丢弃的临时变量)的最后一行,我假设您打算设置*nfile = newNode(通过指针分配给调用者的变量)。

于 2013-01-17T19:31:25.897 回答