为什么对字符串进行完美的释放会导致“free():下一个大小无效”?

发布于 2024-12-09 11:02:38 字数 2526 浏览 1 评论 0原文

糟糕的问题

代码突然按预期工作了。我不记得从崩溃到现在,除了添加一些 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#

BAD QUESTION

The code suddenly works as it should. I can't recall having changed the code at all from when it crashed to now, other than adding some printfs for debugging. I just removed the comment from free(c); and now it works.

So please remove this question


The free on line 48 is the one in question. Once I remove it, my program runs fine, but with memory leakage of course. The string is malloced, filled by sprintf and attempted freed, but unsuccessfully.

I've pastebinned the function by demand
int extcommand(char** param)

The free line causes the following carnage:

*** 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

Why can't I free my string?

Here is some extra information

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#

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

掐死时间 2024-12-16 11:02:38

您遇到了所谓的“堆损坏”。这是当你去破坏(即更改)一些不属于你的内存时 - 也许你在 malloc 给你的块之前编写,或者也许在这样的块结束之后,也许你在释放一个块后使用了它,等等。

堆损坏的问题是你并不总是在搞砸的那一刻崩溃。腐败现象往往会暂时被忽视;您的程序甚至可能在堆管理器注意到之前终止。但一旦发生,您的程序可能会在与原始错误完全无关的点崩溃。这是爱因斯坦所讨厌的那种怪异的超距作用。

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

You have what is known as 'heap corruption'. This is when you go and corrupt (ie, change) some memory that doesn't belong to you - maybe you wrote before the block malloc gave you, or maybe after the end of such a block, maybe you used a block after you freed it, etc.

The thing about heap corruption is you don't always crash at the very moment that you screw up. Often the corruption goes unnoticed for a while; your program may even terminate before the heap manager notices. But once it does, your program may crash at a point completely unrelated to the original error. It's the kind of spooky action-at-a-distance that Einstein would have hated.

The easiest way to track down this sort of thing is to run your program in valgrind; valgrind identifies a number of common heap corruptions and will report stacktraces that point at the actual moment in which the corruption occurred. You can then go and fix the root cause of the error.

一个人的旅程 2024-12-16 11:02:38

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

Well, the obvious answer is that the sprintf is printing more characters than there is allocated space, so that some info on the end of the block (containing bookkeeping info for the memory manager) is being overwritten. Without examining the whole program, there are too many uncertainties here for us to diagnose it perfectly. For example, we don't know what param points to, and how you guarantee it's not too long. You could use snprintf to do this more safely.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文