编辑: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 回答
你是如何初始化你的第一个节点的?
你说“前几个字导致了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检测到它已到达列表的末尾并尝试打印奇怪的东西,导致段错误 .gdb(或另一个调试器,如果你不使用linux)是我追踪段错误的首选工具 . 使用调试符号编译代码并在调试器中运行它 . 崩溃时,检查导致崩溃的线路 . 根据需要使用backtrace命令 . 按照这些步骤,我总是告诉我如何修复段错误 .
我最好的猜测是strncpy而不是strcpy会解决你的问题,听起来有些东西已经在列表后面的某个地方覆盖了你的'next'指针,并且'in'中的字符串太长了肯定会这样做 .
不要忘记strncpy不会终止太长的字符串,所以要确保放置
确保字符串正确终止 .
这是一个风格的评论(SO人们不会欣赏; - [)普通for循环有什么问题?当为这种事物存在有效的惯用结构时,为什么要在循环内部进行迭代?