在malloc.c中断言:2453

我有以下程序试图标记一个字符串(基于空格)并将其写入char **数组。

#include  #include  #define len 180 void tokenize(char *str, char **tokens) { int l = 0, index = 0; int i = 0; int str_i; int tok_i; while(*str) { if (*str == ' ') { tokens[i] = malloc(sizeof(char) * l+1); if (tokens[i] == NULL) return; tok_i = 0; for (str_i=index-len ; str_i<index ; str_i++) { tokens[i][tok_i] = str[str_i]; tok_i++; } tokens[i][tok_i] = '\0'; tokens[i++] = NULL; l = 0; index++; } str++; l++; index++; } return; } int main() { char str[len] = "this is a test string"; char **tokens = malloc(100 * sizeof(char *)); if (str == NULL || tokens == NULL) return 1; printf("input string: %s\n", str); tokenize(str, tokens); return 0; } 

上面的程序编译得很好,但是在执行时,我在malloc.c得到了以下断言

 $ gcc -ggdb -Wall prog.c $ ./a.out input string: this is a test string a.out: malloc.c:2453: 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. Aborted (core dumped) $ 

堆栈跟踪显示以下内容:

 (gdb) bt #0 0x0000003b28036285 in raise () from /lib64/libc.so.6 #1 0x0000003b28037b9b in abort () from /lib64/libc.so.6 #2 0x0000003b2807d37d in __malloc_assert () from /lib64/libc.so.6 #3 0x0000003b28080c37 in _int_malloc () from /lib64/libc.so.6 #4 0x0000003b28082595 in malloc () from /lib64/libc.so.6 #5 0x000000000040055f in tokenize (str=0x7fffffffe017 " a test string", tokens=0x601010) at prog.c:15 #6 0x00000000004006de in main () at prog.c:46 (gdb) 

我该如何调试? 任何想法都将受到高度赞赏。

在你的for循环中

 for (str_i=index-len ; str_i 

str_i是负数。

 for (str_i=index-len ; str_i 

这些tokens[i][tok_i]至少有一个位于已分配的内存之外,因此您最终会破坏malloc的内部信息。 在那之后, 欢闹随之而来 。

str_i初始化也很有趣,因为第一次迭代它将是-180。

是的,根据@cnicutar和@spicavigo的建议,我更改了代码如下,它运行正常。

 #include  #include  #define str_len 180 void tokenize(char *str, char **tokens) { int length = 0, index = 0; int i = 0; int str_i; int tok_i; while(str[length]) { if (str[length] == ' ') { /* this charecter is a space, so skip it! */ length++; index++; tokens[i] = malloc(sizeof(char) * (index+1)); tok_i = 0; for (str_i=length-index ; str_i