2012-11-01 5 views
5

Ich schrieb dieses unschuldige Stück Code, und die Ergebnisse in einer solchen bösen Fehler:SIGABRT in malloc.c, was ist gerade passiert?

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

Ausgabe von debug (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) 

ich die übergebenen Argumente geprüft, auch. Sie waren genau so, wie sie sein sollten:

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) 

kann mir jemand vorstellen, was schief geht hier? Ich weiß, dass es Funktionen gibt, um zwei Saiten miteinander zu verbinden, aber ich möchte es alleine machen!

Mit freundlichen Grüßen.

+3

Das sieht aus wie Haufen Korruption. Der tatsächliche Fehler könnte fast überall in Ihrem Code sein, möglicherweise weit, weit weg von diesem Block. – Mat

+0

Libc bestrafte Sie für den Rückgabewert von 'malloc()'. –

+0

nur durch den Weg: 'newalloc_size = ... + 1' um' 0' zu beenden – slashmais

Antwort

7

Dies riecht wie ein Speicherleck oder Pufferüberlauf (oder eine andere Heap-Beschädigung) an anderer Stelle in Ihrem Programm. Ich schlage vor, es unter Verwendung der -Wall -g Optionen zu gcc neu zu kompilieren, um Ihr Programm zu verbessern, bis keine Warnungen vom Compiler gegeben werden, und valgrind und gdb zu verwenden, um das Problem zu debuggen.

Eigentlich Ihre Aussage

result = (char*) malloc(newalloc_size); 

ist falsch (Platzmangel für die abschließende Null-Byte). Sie wollen wahrscheinlich

result = malloc(newalloc_size+1); 

aber Sie sollten asprintf

+1

'' valgrind'' ist wirklich der Weg, hier zu gehen. –

+0

Danke. Der fehlende Null-Char wurde nicht oben im Code hinzugefügt, ist aber bereits in meinem Code. Vor dem Hinzufügen der +1 einfach kopiert! Trotzdem danke! Ich werde Valgrind und Asprintf betrachten. – musicmatze

3

aus dem Code, die wahrscheinlichste Antwort verwenden lernen ist, dass Sie nullterminierten Strings verwenden und nicht für die abschließende Null im Puffer ermöglicht Raum, den Sie zuordnen.

Versuchen Sie diese statt der Zeile, die Sie haben:

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

Die abschließende Null außerhalb Ihres malloc'd Puffer geschrieben wird, wo es wahrscheinlich Teil von malloc internen Buchhaltung wird überschrieben wird. Dies führt zu einer Heap-Beschädigung, die früher oder später dazu führt, dass malloc bricht.

-1

Ich habe versucht, zu viel Speicher zuzuordnen und bekam auch den bösen Fehler (Fehlercode: EXC_I386_INVOP).

Ich habe es über die Diagnose-Tools (in XCode 6.1.1) in Product/Scheme/Edit Scheme ... und dann in Run/Diagnose verfolgt.