malloc.c中的SIGABRT,是什么意思?

8
我写了这个无辜的代码,结果产生了如此恶意的错误:
static char * prefixed( char * pref, char *str ) {
    size_t newalloc_size = sizeof(char) * (strlen(pref) + strlen(str));
    char * result = (char*) malloc( newalloc_size );
    [...]

来自调试 (cgdb) 的输出:

Breakpoint 1, prefixed (pref=0x401345 "Env: ", str=0x4012b5 "Home") at ./src/backend/os/env.c:77
(gdb) s
(gdb) p newalloc_size 
$1 = 9
(gdb) s
envtest: malloc.c:2368: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >=
(unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)'
failed.

Program received signal SIGABRT, Aborted.
0x00007ffff7a68fd5 in raise () from /usr/lib/libc.so.6
(gdb)  

我也检查了传递的参数。它们正如预期的那样:

Breakpoint 1, prefixed (pref=0x401345 "Env: ", str=0x4012b5 "Home") at ./src/backend/os/env.c:77
(gdb) p pref
$2 = 0x401345 "Env: "
(gdb) p strlen(pref)
$3 = 5
(gdb) p str
$4 = 0x4012b5 "Home"
(gdb) p strlen(str)
$5 = 4
(gdb) 

有人能想象这里出了什么问题吗?我知道有函数可以将两个字符串连接在一起,但我想自己完成它!

此致敬礼。


3
那看起来像是堆栈损坏。实际的错误可能在你的代码任何地方,可能远离那个代码块很远。 - Mat
Libc惩罚您强制转换malloc()的返回值。 - user529758
顺便提一下:newalloc_size = ... + 1 是为了容纳终止的 0 - slashmais
3个回答

12

这似乎是一个内存泄漏或缓冲区溢出(或其他堆栈破坏)在程序的其他位置。我建议使用-Wall -g选项重新编译gcc来改进您的程序,直到编译器不再给出警告,并使用valgrindgdb调试问题。

事实上,你的陈述

  result = (char*) malloc( newalloc_size );

有问题(缺少终止空字节的空间)。您可能想要

  result = malloc(newalloc_size+1);

但是你应该学会使用asprintf


2
在这里,valgrind 真的是最好的选择。 - Jonas Schäfer
谢谢。那段代码中缺失的零字符没有被添加,但已经在我的代码中了。在加上+1之前只是复制了一下!无论如何,谢谢!我会看看valgrind和asprintf的。 - musicmatze

4

从你的代码来看,最有可能的答案是你正在使用以null结尾的字符串,并且没有在你分配的缓冲区中留出空间来容纳终止的null。

尝试使用以下行代替你目前的行:

size_t newalloc_size = sizeof(char) * (strlen(pref) + strlen(str) + 1);

终止空字符被写在您的malloc'd缓冲区之外,这可能会覆盖malloc内部簿记的一部分。 这将导致堆破坏,迟早会导致malloc崩溃。


-1
我尝试分配了太多的内存,结果也得到了邪恶的错误(错误代码:EXC_I386_INVOP)。
通过诊断工具(在XCode 6.1.1中)的Product/Scheme/Edit Scheme...然后在Run/Diagnosis中追踪到这个问题。

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