我正在开发一个函数,它必须采用一个动态字符数组,用空格分隔它,并将每个单词放入一个字符数组的数组中。这是代码:
char** parse_cmdline(const char *cmdline)
{
char** arguments = (char**)malloc(sizeof(char));
char* buffer;
int lineCount = 0, strCount = 0, argCount = 0;
int spaceBegin = 0;
while((cmdline[lineCount] != '\n'))
{
if(cmdline[lineCount] == ' ')
{
argCount++;
arguments[argCount] = (char*)malloc(sizeof(char));
strCount = 0;
}
else
{
buffer = realloc(arguments[argCount], strCount + 1);
arguments[argCount] = buffer;
arguments[argCount][strCount] = cmdline[lineCount];
strCount++;
}
lineCount++;
}
arguments[argCount] = '\0';
free(buffer);
return arguments;
}
问题是我在某个地方遇到了段错误,但我不知 Prop 体在哪里。 此外,该函数的当前版本假定字符串不以空格开头,这是为了下一个版本,我可以处理,但我找不到段的原因。故障
最佳答案
这段代码肯定不是你想要的:
char** arguments = (char**)malloc(sizeof(char));
它为一个char
分配足够大的内存块,并设置一个char **
类型的变量(arguments
)指向给它。但是,即使您只想在 arguments
中为单个 char *
分配足够的空间,您分配的空间也是不够的(在您可能遇到的任何 C 系统上都不是,反正)。对于多个指针来说肯定不够长。
假设在您的 C 系统上指针确实比单个 char
宽,您的程序一旦取消引用 arguments
就会调用未定义的行为。段错误是更可能的结果之一。
最简单的方法可能是扫描输入字符串两次:一次计算单个参数的数量,以便为指针分配足够的空间,然后再次创建单个参数字符串和记录指针它们在你的数组中。
另请注意,返回值不包含任何有关分配了多少空间或因此提取了多少参数字符串的可访问信息。解决这类问题的通常方法是为一个额外的指针分配空间,并将最后一个指针设置为 NULL
作为标记。这与使用空 char
来标记 C 字符串的结尾非常相似,但并不相同。
编辑添加:
arguments
的分配更像这样:
arguments = malloc(sizeof(*arguments) * (argument_count + 1));
也就是说,为一个比参数多的对象分配空间,每个对象的大小与 arguments
旨在指向的事物类型相同。 arguments
的值未被 sizeof
访问,因此此时它是否不确定并不重要。
编辑添加:
最后的 free()
调用也有问题:
free(buffer);
此时,变量 buffer
指向与 arguments
的最后一个元素指向(或旨在指向)相同的分配 block 。如果释放它,则指向该内存的所有 指针都将失效,包括您将要返回给调用者的指针。你不需要在那个时候释放 buffer
,正如你不需要在任何其他分配之后释放它一样。
关于C 将动态字符数组转换为字符数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34580371/