首页 文章

链表中的分段错误

提问于
浏览
3

编辑: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%的ish将显示正常,然后它会在没有警告的情况下进行分段 .

通过更多的检查,它会以与它们相加的相反顺序(有意义)读回单词,并且在分割之前将达到列表末尾的第5个单词(添加的第5个单词) . 我已经尝试调整插入函数以允许超过40个字符串的字符串,但是在开头插入的字(并且是segfaulted)都在20个字符以下 .

随着更多的挖掘,如果我在printList函数中printf l2-> next-> next-> next-> next,那么插入的第一个单词就在那里 .

有人可能会指出我正确的方向吗?

谢谢

4 回答

  • 2

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

    你说“前几个字导致了seg故障”,但是中断可能会阻止他们打印,问题实际上是在最后 .

    我的假设(并且's really just a guess :P) is that your first node doesn'有 next = NULL; ,它's just uninitialised memory. Therefore the while loop doesn't检测到它已到达列表的末尾并尝试打印奇怪的东西,导致段错误 .

  • 2

    gdb(或另一个调试器,如果你不使用linux)是我追踪段错误的首选工具 . 使用调试符号编译代码并在调试器中运行它 . 崩溃时,检查导致崩溃的线路 . 根据需要使用backtrace命令 . 按照这些步骤,我总是告诉我如何修复段错误 .

  • 3

    我最好的猜测是strncpy而不是strcpy会解决你的问题,听起来有些东西已经在列表后面的某个地方覆盖了你的'next'指针,并且'in'中的字符串太长了肯定会这样做 .

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

    x[39]=0;
    

    确保字符串正确终止 .

  • 2

    这是一个风格的评论(SO人们不会欣赏; - [)普通for循环有什么问题?当为这种事物存在有效的惯用结构时,为什么要在循环内部进行迭代?

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

相关问题