我正在尝试用c编写一个简单的split函数,在这里你提供一个字符串和一个字符来进行拆分,然后它返回一个拆分字符串的列表:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char ** split(char * tosplit, char delim){
int amount = 0;
for (int i=0; i<strlen(tosplit); i++) {
if (tosplit[i] == delim) {
amount++;
}
}
char ** split_ar = malloc(0);
int counter = 0;
char *token = strtok(tosplit, &delim);
while (token){
split_ar[counter] = malloc(0);
split_ar[counter] = token;
token = strtok(NULL, &delim);
counter++;
}
split_ar[counter] = 0;
return split_ar;
}
int main(int argc, char *argv[]){
if (argc == 2){
char *tosplit = argv[1];
char delim = *argv[2];
char ** split_ar = split(tosplit, delim);
while (*split_ar){
printf("%s\n", *split_ar);
split_ar++;
}
} else {
puts("Please enter words and a delimiter.");
}
}
我使用malloc两次:一次是为指向字符串的指针分配空间,一次是为实际的字符串本身分配空间。奇怪的是:在测试过程中,我发现当我没有分配任何空间时,代码仍然可以工作。
当我删除malloc-line时,我得到了Segfaults或Malloc-assertion错误,所以这些行看起来确实是必要的,尽管它们看起来没有做任何事情。有人能解释一下为什么吗?
我想这和strtok有关;被标记的字符串是在函数作用域之外初始化的,strtok返回指向原始字符串的指针,所以malloc可能根本就不是必需的。我看过许多老的SO线程,但没有找到足够相似的东西来回答我的问题。
1条答案
按热度按时间uqdfh47h1#
为什么C语言中的malloc(0)不会产生错误...?
为什么代码可以在
malloc(0)
的情况下工作。调用
malloc(0)
是可以的。稍后在split_ar[counter] = malloc(0);
中使用该指针是 * 未定义的行为 *(UB),因为即使split_ar[0]
也试图访问分配的内存之外的内容。当代码引发 * 未定义行为 * 时,没有应该 * 产生错误 。这是未定义行为。 未定义行为 * 中没有 * 已定义行为 *。它可能“工作”,也可能不工作。这是UB。
C并没有给弱编程增加safeguards。
如果您需要一种语言来添加对此类错误的额外检查,C并不是最好的答案。
相反,分配正确的数量。在OP的情况下,我认为它最多是
amount + 2
。(考虑tosplit
不包含任何分隔符的情况。)进一步
代码只尝试复制指针而不复制字符串。
相反,为字符串分配并复制字符串,研究
strdup()
。高级
1.使用
strspn()
和strcspn()
遍历一个sing并对其进行解析,这样做的好处是可以操作const
字符串,并且很容易知道令牌的大小,这在分配时非常有用。1.使用相同的技术两次来预先计算标记计数和解析。这避免了OP的2个方法中存在的差异。