为什么字符串上的完全免费会导致“free():next size”?

时间:2011-10-13 02:19:46

标签: c gcc free glibc

坏问题

代码突然正常运行。我记不起已经从崩溃到现在完全改变了代码,除了为调试添加一些printf。我刚刚从free(c);删除了评论,现在可以了。

所以请删除这个问题


免费在线48是有问题的。一旦我删除它,我的程序运行正常,但当然内存泄漏。该字符串为malloc,由sprintf填充并尝试释放,但未成功。

我按要求将该功能粘贴到了 int extcommand(char** param)

免费线造成以下大屠杀:

*** glibc detected *** ./bin/tomashell: free(): invalid next size (fast): 0x094e7030 ***
======= Backtrace: =========
/lib/i686/cmov/libc.so.6(+0x6b281)[0xb7656281]
/lib/i686/cmov/libc.so.6(+0x6cad8)[0xb7657ad8]
/lib/i686/cmov/libc.so.6(cfree+0x6d)[0xb765abbd]
./bin/tomashell[0x8048ffb]
./bin/tomashell[0x8048e28]
./bin/tomashell[0x8048c37]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb7601c76]
./bin/tomashell[0x8048751]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 08:01 5578979    /root/Dropbox/UIO/INF1060/hjemmeeksamen-1/tomashell/bin/tomashell
0804a000-0804b000 rw-p 00001000 08:01 5578979    /root/Dropbox/UIO/INF1060/hjemmeeksamen-1/tomashell/bin/tomashell
094e7000-09508000 rw-p 00000000 00:00 0          [heap]
b7400000-b7421000 rw-p 00000000 00:00 0
b7421000-b7500000 ---p 00000000 00:00 0
b75c5000-b75e2000 r-xp 00000000 08:01 1843203    /lib/libgcc_s.so.1
b75e2000-b75e3000 rw-p 0001c000 08:01 1843203    /lib/libgcc_s.so.1
b75ea000-b75eb000 rw-p 00000000 00:00 0
b75eb000-b772b000 r-xp 00000000 08:01 1860235    /lib/i686/cmov/libc-2.11.2.so
b772b000-b772d000 r--p 0013f000 08:01 1860235    /lib/i686/cmov/libc-2.11.2.so
b772d000-b772e000 rw-p 00141000 08:01 1860235    /lib/i686/cmov/libc-2.11.2.so
b772e000-b7731000 rw-p 00000000 00:00 0
b7736000-b773a000 rw-p 00000000 00:00 0
b773a000-b773b000 r-xp 00000000 00:00 0          [vdso]
b773b000-b7756000 r-xp 00000000 08:01 1843225    /lib/ld-2.11.2.so
b7756000-b7757000 r--p 0001a000 08:01 1843225    /lib/ld-2.11.2.so
b7757000-b7758000 rw-p 0001b000 08:01 1843225    /lib/ld-2.11.2.so
bf9f8000-bfa0d000 rw-p 00000000 00:00 0          [stack]
Aborted

为什么我不能释放我的字符串?

以下是一些额外信息

root@chu:~/sc/tomashell# gcc --version
gcc (Debian 4.4.5-8) 4.4.5
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

root@chu:~/sc/tomashell# uname -a
Linux chu 2.6.32-5-686 #1 SMP Mon Jun 13 04:13:06 UTC 2011 i686 GNU/Linux
root@chu:~/sc/tomashell#

2 个答案:

答案 0 :(得分:3)

你有所谓的'堆腐败'。这是当你去腐败(即,改变)一些不属于你的记忆 - 也许是你在阻止malloc给你之前写的,或者也许是在这样一个阻止结束之后写的,也许你用了一个你释放它后阻止等等。

关于堆损坏的事情是你在搞砸的那一刻并不总是崩溃。腐败常常被忽视一段时间;您的程序甚至可能在堆管理器通知之前终止。但是一旦它发生,你的程序可能会在与原始错误完全无关的点崩溃。这是爱因斯坦所讨厌的那种幽灵般的动作。

追踪此类事情的最简单方法是在valgrind中运行您的程序; valgrind识别了许多常见的堆损坏,并将报告指向发生损坏的实际时刻的堆栈跟踪。然后,您可以去解决错误的根本原因。

答案 1 :(得分:2)

嗯,显而易见的答案是sprintf打印的字符多于分配的空格,因此块的末尾有一些信息(包含内存管理器的簿记信息)被覆盖。在没有检查整个程序的情况下,我们有太多不确定因素可以完美地诊断它。例如,我们不知道param指向的是什么,以及您如何保证它不会太久。您可以使用snprintf更安全地执行此操作。