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

标签 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,它告诉我这是一个错误within malloc。 (我希望我是错的。)
  • 当我通过 valgrind 运行相同的二进制文件时,它按预期工作。
  • 这似乎不是变量声明 o->data 的问题,这是一个 字符*。如果我声明 char* A; A = 而不是 o->data = 它仍然崩溃。

如果有任何关于如何排除故障/为什么会发生这种情况的想法,我将不胜感激。

谢谢!

最佳答案

所以,我想我找到了。我们可能需要将其归档在“Sean 需要学习基本的 Valgrind 技能”下。这是我为任何 future 的观察者解决它的方法。

  1. 好的,我们正在处理一个由久经考验的库抛出的非常奇怪的错误 功能,所以它必须是特定于我的设置的东西。算法是一样的 所以它一定是数据
  2. 动态内存实现有一个底层数据结构来跟踪分配 内存,它恰好是一个双向链表——因此是消息。
  3. 所以,一定有某处内存操作破坏这个数据结构 一种微妙的方式。
  4. 好的,我们可以使用哪些工具? valgrind好评如潮,试试看 那。奇怪,它在 Valgrind 中有效。嗯。
  5. 实际阅读 Valgrind 告诉您的内容。 (这是我没有尽我所能的地方。)它 将您标记为错误,例如“大小 1 的无效写入”以及 出现的各种标签/符号。寻找可能的错误并调整为 必要的。
  6. 在这种情况下,它指向我调用 hashtable_put 中的 memcpy() hashtable.c 的函数。微妙的暗示是我传递了第一个参数 使用寻址运算符 & 到 memcpy,这导致了损坏。
  7. 当我解决这个问题时,Valgrind 不再提示。

故事的寓意:

  • 不要忽视来自工具的反馈。没有消息通常是好消息,所以如果 Valgrind 吐出大量信息,这增加了出现问题的可能性。
  • 动态内存分配错误很微妙(真正意义上的动态) 并且会受到许多变量的影响。 Valgrind 把东西放在你的中间 程序和内存库,所以它知道发生了什么,所以我认为这些受到影响 程序以某种方式运行。

到目前为止已解决问题的提交:

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

关于c - malloc() 崩溃,说损坏的双链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18035080/

相关文章:

c - 为什么gdb8.2在Centos7 aliyun上编译出错?

c - 如果 malloc 通过 gdb 返回 NULL,如何设置条件断点

C 结构初始化 - 有趣

c - 如何对 char 字符串/数组使用 malloc() 函数?

c++ - 在不使用静态成员的情况下跨对象树共享数据的策略

c++ - 从构建配置创建 Makefile

c - 水的状态(温度程序)- C 编程

c - Mach 信号量是否在进程之间的共享内存中工作?

c - 我的 malloc/realloc 有什么问题吗?

c - 以下是二维数组吗?