malloc()崩溃,说损坏的双链表

时间:2013-08-03 16:44:21

标签: c malloc

修改完整来源:

http://code.seanwoods.com/reynard.fossil.cgi/artifact/0cc9cbfbe021c2ba86dcb4d0cf6ada52f0a80063

在这里拨打电话:

http://code.seanwoods.com/reynard.fossil.cgi/artifact/891405e62c95349aaf461dfb8ba82259f77fac9b

我有一个相对简单的内存分配失败了。虽然它确实在几个地方分配内存,但应用程序并不是特别复杂。它是C,而不是C ++。我很肯定这是分配内存的问题,而不是释放内存。

以下是代码:

printf(":2 %d %d\n", initial_len, initial_len * sizeof(char));
o->data = (char*) malloc(initial_len * sizeof(char));
printf(":3 \n");

执行后,我得到:

:1
:2 1024 1024
*** glibc detected *** ./menv: corrupted double-linked list: 0x0000000001d14400 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7f680cfc4d76]
/lib/x86_64-linux-gnu/libc.so.6(+0x771ed)[0x7f680cfc51ed]
/lib/x86_64-linux-gnu/libc.so.6(+0x794d4)[0x7f680cfc74d4]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x70)[0x7f680cfc9b90]
./menv[0x403971]
./menv[0x40391d]
./menv[0x4030ec]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7f680cf6cead]
./menv[0x401369]
======= Memory map: ========
00400000-00405000 r-xp 00000000 08:03 2621441                            /home/swoods/code/reynard/modules/stdlib/menv
00605000-00606000 rw-p 00005000 08:03 2621441                            /home/swoods/code/reynard/modules/stdlib/menv
00606000-00706000 rw-p 00000000 00:00 0 
01cfd000-01d3d000 rw-p 00000000 00:00 0                                  [heap]
7f6808000000-7f6808021000 rw-p 00000000 00:00 0 
7f6808021000-7f680c000000 ---p 00000000 00:00 0 
7f680cd38000-7f680cd4d000 r-xp 00000000 08:05 10354962                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f680cd4d000-7f680cf4d000 ---p 00015000 08:05 10354962                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f680cf4d000-7f680cf4e000 rw-p 00015000 08:05 10354962                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f680cf4e000-7f680d0ce000 r-xp 00000000 08:05 10354980                   /lib/x86_64-linux-gnu/libc-2.13.so
7f680d0ce000-7f680d2ce000 ---p 00180000 08:05 10354980                   /lib/x86_64-linux-gnu/libc-2.13.so
7f680d2ce000-7f680d2d2000 r--p 00180000 08:05 10354980                   /lib/x86_64-linux-gnu/libc-2.13.so
7f680d2d2000-7f680d2d3000 rw-p 00184000 08:05 10354980                   /lib/x86_64-linux-gnu/libc-2.13.so
7f680d2d3000-7f680d2d8000 rw-p 00000000 00:00 0 
7f680d2d8000-7f680d2da000 r-xp 00000000 08:05 10354973                   /lib/x86_64-linux-gnu/libdl-2.13.so
7f680d2da000-7f680d4da000 ---p 00002000 08:05 10354973                   /lib/x86_64-linux-gnu/libdl-2.13.so
7f680d4da000-7f680d4db000 r--p 00002000 08:05 10354973                   /lib/x86_64-linux-gnu/libdl-2.13.so
7f680d4db000-7f680d4dc000 rw-p 00003000 08:05 10354973                   /lib/x86_64-linux-gnu/libdl-2.13.so
7f680d4dc000-7f680d4fc000 r-xp 00000000 08:05 10354984                   /lib/x86_64-linux-gnu/ld-2.13.so
7f680d6df000-7f680d6e2000 rw-p 00000000 00:00 0 
7f680d6f8000-7f680d6fb000 rw-p 00000000 00:00 0 
7f680d6fb000-7f680d6fc000 r--p 0001f000 08:05 10354984                   /lib/x86_64-linux-gnu/ld-2.13.so
7f680d6fc000-7f680d6fd000 rw-p 00020000 08:05 10354984                   /lib/x86_64-linux-gnu/ld-2.13.so
7f680d6fd000-7f680d6fe000 rw-p 00000000 00:00 0 
7ffff3bd6000-7ffff3bf7000 rw-p 00000000 00:00 0                          [stack]
7ffff3bff000-7ffff3c00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted
  • 代码编译没有问题。
  • 当我“独立”运行它时,它会因上面的错误而崩溃。我看到:2,但我看不到 :3,它告诉我在malloc 中出现错误。 (我希望我错了。)
  • 当我通过valgrind运行相同的二进制文件时,它会按预期工作。
  • 变量声明o->data似乎不是问题,这是一个问题 char*。如果我声明char* A; A =而不是o->data =,它仍然会崩溃。

我非常感谢有关如何进行故障排除/为什么会发生这种情况的任何想法。

谢谢!

2 个答案:

答案 0 :(得分:15)

所以,我想我找到了它。我们可能需要在“Sean需要学习基本的Valgrind技能”下提交。以下是我为未来观察者解决的问题。

  1. 好的,我们正在处理一个经过试验和测试的库引发的一个非常奇怪的错误 功能,所以它必须是我的设置特定的东西。算法是一样的, 所以它必须是数据
  2. 动态内存实现具有跟踪已分配的基础数据结构 内存,恰好是一个双向链表 - 因此就是消息。
  3. 因此,必须在破坏此数据结构的地方进行内存操作 一种微妙的方式。
  4. 好的,我们可以使用哪些工具? Valgrind受到高度赞扬,让我们试试吧 那。奇怪,它适用于Valgrind。 HMM。
  5. 实际上阅读了Valgrind告诉你的内容。 (这是我没有尽我所能的地方。)它 标记您有错误,如“无效写入大小1”以及跟踪的痕迹 出现的各种标签/符号。寻找可能的错误并调整为 必要的。
  6. 在这种情况下,它指的是memcpy()hashtable_put的调用 hashtable.c的功能。微妙的提示是我传递了第一个参数 使用地址操作符&进行memcpy,导致损坏。
  7. 当我解决这个问题时,Valgrind不再抱怨了。
  8. 故事的寓意:

    • 不要忽略工具的反馈。没有消息[通常]是好消息,所以如果Valgrind 吐出很多信息,他们的问题可能性增加。
    • 动态内存分配错误是微妙的(动态在真正意义上的单词) 并且可能受到许多变量的影响。 Valgrind把东西放在你的中间 程序和内存库所以它知道发生了什么,所以我认为这些受到了影响 程序的操作不知何故。

    到目前为止修正问题的提交:

    http://code.seanwoods.com/reynard.fossil.cgi/ci/bd6a5a23c1?sbs=0

答案 1 :(得分:-1)

编辑: 由于我们几乎不知道你的struct o是什么样的以及数据类型o->data应该是什么,我们只能推测你想要做的事情。

请指定o结构定义,以便我们提供帮助。