C语言 链表中的分段错误



编辑:Dijkstra的答案是解决此问题的方法。我的列表未初始化为 NULL

我正在处理一个链表来存储一个唯一的单词列表,当我尝试遍历列表时会出现段错误。Gdb 给我:

    Program received signal SIGSEGV, 
    Segmentation fault. 0x0000003a07e47ff7 in vfprintf () from /lib64/libc.so.6 
    Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.7.el6_0.5.x86_64

列表的插入代码为:

typedef struct L { char x[40] ; int occ; struct L *next ;} List;
List *insertList( char *in, List *l )
{
    List *t = calloc( 1, sizeof( List ) ) ;
    strcpy(t->x, in);
    t->occ = 1;
    t->next = l ;
    return t ;
}
void printList(List *l)
{
    List *l2 = l;
    while(l2)
    {
        printf("%s ", l2->x);
        l2 = l2->next;
    }
    return;
}

它循环遍历单词,将它们插入链表中,似乎很好。当我循环浏览列表以显示单词(大约 4200 个单词(时,大约 98% 的单词将显示正常,然后它会在没有警告的情况下出现段错误。

再进行一些检查,它会以与添加单词相反的顺序读回单词(这是有道理的(,并且在段错误之前将到达列表末尾的第 5 个单词(添加的第 5 个单词(。我尝试调整插入功能以允许超过 40 个字符长的字符串,但是在开头插入(并且被段错误(的单词都低于 20 个字符。

通过更多的挖掘,如果我在printList函数中printf l2->next->next->next->next-next,则插入的第一个单词就在那里。

谁能用这个为我指出正确的方向?

谢谢

gdb(如果你不使用Linux,或者另一个调试器(是我跟踪段错误的选择工具。使用调试符号编译代码并在调试器中运行它。崩溃时,请检查导致崩溃的线路。根据需要使用回溯命令。遵循这些步骤几乎总是向我展示如何修复段错误。

我最好的猜测是 strncpy 而不是 strcpy 可以解决您的问题,听起来好像有什么东西覆盖了列表后期的某个地方的"下一个"指针,而"in"中太长的字符串肯定会做到这一点。

不要忘记 strncpy 不会终止太长的字符串,所以要确保将

x[39]=0;

以确保字符串将正确终止。

你如何初始化你的第一个节点?

你说"前几个词导致了赛格错误",但中断可能会阻止他们打印,问题实际上就在最后。

我的假设(实际上只是一个猜测:P(是你的第一个节点没有next = NULL;,它只是未初始化的内存。因此,while 循环不会检测到它已到达列表的末尾,并尝试打印一些奇怪的内容,从而导致段错误。

这是一个文体评论(SO的人不会欣赏;-[ (普通的 for 循环有什么问题?当这种事情有一个有效的习惯构造时,为什么要在循环内迭代?

void printList(List *lp)
{
    List *l2;
    for(l2=lp; l2; l2 = l2->next)
    {
        printf("%s ", l2->x);
    }
    return;
}

相关内容

  • 没有找到相关文章