我在编写带分隔符的字符串拆分函数时遇到问题。我的功能基于这里的主要功能:http://www.cplusplus.com/reference/cstring/strtok/。
当我通过main测试它时,我只能传递char [],但不能传递char *。传递char *时,程序seg出错。
即。通过str_split传递一些char str []但不是一些char * str。任何帮助将不胜感激。
char** str_split(char* str, const char* delim)
{
char* tmp;
char** t = (char**)malloc(sizeof(char*) * 1024);
char** tokens = t;
tmp = strtok(str, delim);
while(tmp != NULL)
{
*tokens = (char*)malloc(sizeof(char) * strlen(tmp));
*tokens = strdup(tmp);
tokens++;
tmp = strtok(NULL, delim);
}
return t;
}
答案 0 :(得分:0)
当我通过main测试它时,我只能传递char [],但不能传递char *。传递char *时,程序seg出错。
由于上述机会,您没有为char *
中的main
分配内存,或者您正在传递字符串文字。
答案 1 :(得分:0)
这两行给出了两个不同的问题:
*tokens = (char*)malloc(sizeof(char) * strlen(tmp));
*tokens = strdup(tmp);
第一行将分配strlen(tmp)
个字节,但问题是字符串有一个额外的字符来终止字符串,所以你真的需要分配strlen(tmp) + 1
个字节。
第二行覆盖你从malloc
获得的原始指针,导致内存泄漏。
另外,在C中你should not cast the return of malloc
。
哦,还有另一个注意事项:sizeof(char)
指定始终返回1
,无论char
类型的实际位大小。
至于你的seg-faulting,我猜你是用字符串文字调用你的函数,比如说。
some_var = str_split("hello world", " ");
或者可能
char *string = "hello world";
some_var = str_split(string, " ");
这会导致取消定义行为,因为字符串文字实际上是指向常量字符数组的指针,而strtok
修改 >字符串。未定义的行为可以说是崩溃的最常见原因。
如果您在构建时启用了更多警告,则会收到关于此的警告,或者您确实会收到警告但忽略它,或使用强制转换来摆脱警告。来自编译器的警告通常是你做一些你不应做的事情的好指标,通过例如隐藏它施放只会使警告静音但不能解决问题。
您的代码还存在其他一些问题。一个是如果只有一个"" /"令牌"在"句子"您传入函数,在该分配中浪费4092
或8184
个字节(取决于32位或64位平台)。您可能希望首先单独执行一个标记化循环(在字符串的临时副本上),以找出"令牌的确切数量"或"字"在输入中。
执行此计数也将解决另一个问题:如果更多而不是1024个令牌/单词怎么办?在这种情况下,你的循环会幸福地写出界限。
这两种情况都是极端的,您的标准用例可能更适合您当前的代码,但它仍然需要考虑。
答案 2 :(得分:0)
您可能会在声明
处为char *分配值char *str="abcdef";
或者您可能没有为char * str
指向的字符串分配内存。在这两种情况下,strtok()
都会生成segmentation fault
。