2012-11-01 23 views
5

tôi đã viết tác phẩm này vô tội mã, và kết quả là một lỗi ác như vậy:SIGABRT trong malloc.c, điều gì vừa xảy ra?

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

đầu ra từ 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) 

Tôi đã kiểm tra các đối số trôi qua, quá. Họ ở đúng như chúng được cho là:

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) 

ai cũng có thể tưởng tượng, điều gì xảy ra ở đây? Tôi biết có chức năng để mèo hai dây với nhau, nhưng tôi muốn làm điều đó một mình!

kính thư.

+3

Trông giống như tham nhũng đống. Lỗi thực tế có thể chỉ là về bất cứ nơi nào trong mã của bạn, có thể xa, cách xa khối đó. – Mat

+0

Libc trừng phạt bạn vì đã gán giá trị trả về của 'malloc()'. –

+0

chỉ bằng cách: 'newalloc_size = ... + 1' để cho phép chấm dứt' 0' – slashmais

Trả lời

7

Điều này có mùi giống như rò rỉ bộ nhớ hoặc tràn bộ đệm (hoặc một số hỏng heap khác) ở nơi khác trong chương trình của bạn. Tôi đề nghị biên dịch lại nó bằng cách sử dụng các tùy chọn -Wall -g để gcc, để cải thiện chương trình của bạn cho đến khi không có cảnh báo nào được trình biên dịch đưa ra và sử dụng valgrindgdb để gỡ lỗi vấn đề.

Trên thực tế, tuyên bố của bạn

result = (char*) malloc(newalloc_size); 

là sai (thiếu không gian cho việc chấm dứt vô byte). Bạn có thể muốn

result = malloc(newalloc_size+1); 

nhưng bạn nên học cách sử dụng asprintf

+1

'' valgrind'' thực sự là cách để đi đến đây. –

+0

Cảm ơn bạn. Thiếu số không-char đã không được thêm vào trong mã trên đó, nhưng đã có trong mã của tôi. Chỉ cần sao chép trước khi thêm +1! Dù sao cũng cảm ơn! Tôi sẽ có một cái nhìn tại valgrind và asprintf. – musicmatze

3

Từ mã của bạn, câu trả lời rất có thể là bạn đang sử dụng null-terminated strings và không cho phép không gian cho các null chấm dứt trong bộ đệm bạn chỉ định.

Hãy thử điều này thay vì các dòng bạn có:

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

Các null kết thúc đang được viết bên ngoài của đệm malloc'd của bạn, nơi nó có thể được ghi đè lên một phần của kế toán nội bộ malloc của. Điều này sẽ gây ra tham nhũng heap, mà sẽ sớm hay muộn gây ra malloc để phá vỡ.

-1

Tôi đã cố gắng phân bổ quá nhiều bộ nhớ và nhận được lỗi xấu quá (mã lỗi: EXC_I386_INVOP).

Tôi đã theo dõi nó xuống thông qua các công cụ chẩn đoán (trong XCode 6.1.1) trong Đề án sản phẩm/sơ đồ/chỉnh sửa ... và sau đó trong Chạy/chẩn đoán.

Các vấn đề liên quan