我的程序出了问题,在这个程序中,我从GDB获得了一个来自strsep()的分段错误,并得到了错误消息。
Program received signal SIGSEGV, Segmentation fault.
0x00002aaaaad64550 in strsep () from /lib64/libc.so.6我的代码如下:
int split(char *string, char *commands, char *character) {
char **sp = &string;
char *temp;
temp = strdup(string);
sp = &temp;
for (int i = 0; i < 100; i++) {
commands[i] = strsep(sp, character);
if (commands[i] == '\0') {
return 0;
}
if (strcasecmp(commands[i], "") == 0) {
i--;
}
printf("%d", i);
}
return 0;
}任何帮助都将不胜感激,因为我花了几个小时试图解决这个问题。
函数的参数是("Hello World", "@", "&")
编辑
因此,我通过将代码更改为
int split(char* string, char* commands, char* character) {
for(int i = 0; i < 100; i++) {
commands[i] = strsep(&string, character);
if(commands[i] == '\0') {
return 0;
}
if(strcasecmp(&commands[i], "") == 0) {
i--;
}
}
return 0;
}然而,现在我遇到了一个新的问题,即命令返回一个空数组,其中每个索引都超出了范围。
编辑2
我还应该澄清一下我想要做的事情,所以本质上,命令是char* commands[100]类型的,当我修改原始指针数组并将‘Hello’存储到命令中时,我希望将它传递到函数中,然后我想在函数之外修改这个值。
发布于 2020-09-13 15:22:22
您使用的commands与函数原型不一致:调用方传递一个100 char*的数组,commands应该是指向char *数组的指针,因此是一个char **commands或char *commands[]类型。为了让调用者确定存储在数组中的令牌的数量,您应该要么在末尾存储一个NULL指针,要么返回这个数字,或者两者都返回。
存储commands[i] = strsep(...)是不正确的,因为commands被定义为char *,而不是char **。
令人惊讶的是,在strsep()中会出现分段错误,因为参数似乎是正确的,除非character恰好是一个无效的指针。
相反,您有未定义的行为,很可能导致strcasecmp(commands[i], "")中的分段错误,因为commands[i]是一个char值,而不是一个有效的指针。
以下是修改后的版本:
// commands is assumed to point to an array of at least 100 pointers
// return the number of tokens or -1 is case of allocation failure
int split(const char *string, char *commands[], const char *separators) {
char *dup = strdup(string + strcspn(string, separators));
if (temp == NULL)
return -1;
char *temp = dup;
char **sp = &temp;
int i = 0;
while (i < 99) {
char *token = strsep(sp, separators);
if (token == NULL) // no more tokens
break;
if (*token == '\0') // ignore empty tokens
continue;
commands[i++] = token;
}
commands[i] = NULL;
if (i == 0) {
free(dup);
}
return i;
}分配给令牌的内存可以通过释放commands数组中的第一个指针来释放。复制这些令牌可能更简单,这样就可以以更通用的方式释放它们。
https://stackoverflow.com/questions/63870916
复制相似问题