我有以下程序尝试对字符串进行标记(基于空格)并将其写入char **数组。
#include <stdio.h>
#include <stdlib.h>
#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)
我该如何调试?任何想法都将受到高度赞赏。
答案 0 :(得分:3)
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][tok_i]
在已分配的内存之外,因此您最终会破坏malloc
的内部信息。之后,hilarity ensues。
str_i
初始化也很有趣,因为第一次迭代它将是-180。
答案 1 :(得分:3)
在你的for循环中
for (str_i=index-len ; str_i<index ; str_i++)
str_i是负数。
答案 2 :(得分:1)
是的,根据@cnicutar和@spicavigo的建议,我更改了以下代码并且工作正常。
#include <stdio.h>
#include <stdlib.h>
#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<length; str_i++) {
tokens[i][tok_i] = str[str_i];
tok_i++;
}
tokens[i][tok_i] = '\0';
i++;
index = 0;
}
length++;
index++;
}
/* copy the last word in the string */
tokens[i] = malloc(sizeof(char) * index);
tok_i = 0;
for (str_i=length-index ; str_i<length; str_i++) {
tokens[i][tok_i] = str[str_i];
tok_i++;
}
tokens[i][tok_i] = '\0';
tokens[i++] = NULL;
return;
}
int main()
{
char *str = malloc(str_len * sizeof(char));
char **tokens = malloc(100 * sizeof(char *));
int i = 0;
if (str == NULL || tokens == NULL)
return 1;
gets(str);
printf("input string: %s\n", str);
tokenize(str, tokens);
while(tokens[i] != NULL) {
printf("%d - %s \n", i, tokens[i]);
i++;
}
while(tokens[i])
free(tokens[i]);
free(tokens);
free(str);
return 0;
}