为什么我会在这里收到 SIGABRT 信号?

16

我有这样一段代码,在其中我正在循环中打开/关闭一个文件:

for(i=1;i<max;i++)
     {
       /* other code */
       plot_file=fopen("all_fitness.out","w");
       for (j=0;j<pop_size;j++)
         fprintf(plot_file, "%lf %lf\n",oldpop[i].xreal[0],oldpop[i].obj);
       fclose(plot_file);
      /*other code*/
     }

我在这里收到了一个SIGABRT信号,并附带以下回溯信息:

#0  0x001fc422 in __kernel_vsyscall ()
#1  0x002274d1 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2  0x0022a932 in *__GI_abort () at abort.c:92
#3  0x0025dee5 in __libc_message (do_abort=2, fmt=0x321578 "*** glibc detected *** %s: %s: 0x%s ***\n")
    at ../sysdeps/unix/sysv/linux/libc_fatal.c:189
#4  0x00267ff1 in malloc_printerr (action=<value optimized out>, str=0x6 <Address 0x6 out of bounds>, ptr=0x8055a60) at malloc.c:6217
#5  0x002696f2 in _int_free (av=<value optimized out>, p=<value optimized out>) at malloc.c:4750
#6  0x0026c7cd in *__GI___libc_free (mem=0x8055a60) at malloc.c:3716
#7  0x0025850a in _IO_new_fclose (fp=0x8055a60) at iofclose.c:88
#8  0x0804b9c0 in main () at ga.c:1100

我在上面的代码片段中执行fclose()的行号是1100。以上行为的原因是什么?非常感谢任何指针。

(我正在使用gcc和Linux操作系统)


1
你在两个循环中都使用了同一个i,这是有意为之吗? - IVlad
@IVlad:感谢您指出。这是问题发布中的错误。已经修复了。 - user59634
malloc_printerr信息是什么意思?你确定fclose()引起了崩溃吗?我认为你应该将代码缩减到导致问题的部分并发布。 - IVlad
你好,我尝试使用一些变量来完成你的代码片段,但没有出现错误。你的代码可以更详细吗? - coelhudo
好奇——在中止时,i的值是多少?它是第一个、最后一个还是在中间某个位置(并且在运行之间是否一致)? - Walt Stoneburner
显示剩余5条评论
2个回答

23

当你调用 fclose() 时,glibc 会释放一些动态分配的结构体;内部有一个 free() 调用。 malloc()free() 靠相当复杂、动态构建的结构来运行。显然,glibc 发现这些结构处于不一致状态,以至于无法进行安全的内存释放。 glibc 决定此问题严重到需要立即中止程序。

这意味着你的代码中可能存在错误,可能远在你展示的片段之外,例如缓冲区溢出或类似的错误导致了内存分配结构的损坏。

你可以尝试使用ValgrindElectric Fence来解决此类问题。


你好 Thomas:是的,错误在别处。Valgrind 帮助我找到了问题所在。感谢你的提示。在看到你的回答后,我真的深入研究了代码,并纠正了一个相当愚蠢、被忽视的错误。 - user59634

1

我不知道它是否导致了你的特定问题,但你应该始终检查fopen()返回的FILE *指针,以防它是NULL


我已经进行了检查,没有什么可疑的。谢谢 :) - user59634

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接