2012-11-01 85 views
5

我寫了這個無辜的代碼,並導致這樣一個邪惡的錯誤:從調試(cgdb)輸出malloc.c中的SIGABRT,剛剛發生了什麼?

static char * prefixed(char * pref, char *str) { 
    size_t newalloc_size = sizeof(char) * (strlen(pref) + strlen(str)); 
    char * result = (char*) malloc(newalloc_size); 
    [...] 

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

+0

Libc懲罰你爲'malloc()'返回值。 – 2012-11-01 16:22:51

+0

只是順便說一句:'newalloc_size = ... + 1'允許終止'0' – slashmais

回答

7

這聽起來像是程序中的內存泄漏或緩衝區溢出(或其他一些堆損壞)其他地方。我建議使用-Wall -g選項將其重新編譯爲gcc,以改進您的程序,直到編譯器未給出警告爲止,並使用valgrindgdb來調試問題。

其實,你的發言

result = (char*) malloc(newalloc_size); 

是錯誤的(缺乏對終止空字節的空間)。你可能想

result = malloc(newalloc_size+1); 

但是你應該學會使用asprintf

+1

''valgrind''真的是這裏的路。 –

+0

謝謝。缺少的零字符沒有被添加到代碼中,但已經在我的代碼中。剛剛複製之前添加+1!不管怎樣,謝謝!我會看看valgrind和asprintf。 – musicmatze

3

從你的代碼中,最有可能的答案是,你正在使用空值終止字符串,而不是允許終止空空間在緩衝區中的分配。

試試這個,而不是你有行:

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

的終止空被你的malloc分配緩衝區,在那裏它可能覆蓋的malloc的內部簿記的部分之外寫入。這會導致堆損壞,遲早會導致malloc崩潰。

-1

我試圖分配太多的內存,並得到了邪惡的錯誤(錯誤代碼:EXC_I386_INVOP)。

我通過產品/方案/編輯方案中的診斷工具(在XCode 6.1.1中),然後在運行/診斷中對其進行了跟蹤。

相關問題