strsep() 导致分段错误
strsep() causing Segmentation fault
我的程序有问题,我从 strsep()
收到了一个分段错误,它是从 GDB 得到的,并且有错误消息
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] == '[=11=]') {
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] == '[=12=]') {
return 0;
}
if(strcasecmp(&commands[i], "") == 0) {
i--;
}
}
return 0;
}
但是现在我遇到了一个新问题,命令返回一个空数组,其中每个索引都超出范围。
编辑 2
我还应该澄清一下我正在尝试做的事情,所以本质上命令是 char* commands[100]
类型的,我想将它传递给函数,然后修改原始指针数组并存储说`" Hello World"' into commands[0] 然后我想在函数外修改这个值。
你对commands
的用法与函数原型不一致:调用者传递了一个100的数组char*
,commands
应该是一个指向[=14=的数组的指针],因此类型 char **commands
或 char *commands[]
。为了让调用者确定存储在数组中的令牌数量,您应该在末尾存储一个 NULL
指针或 return 这个数字或两者。
存储 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 == '[=10=]') // ignore empty tokens
continue;
commands[i++] = token;
}
commands[i] = NULL;
if (i == 0) {
free(dup);
}
return i;
}
可以通过释放 commands
数组中的第一个指针来释放为令牌分配的内存。复制这些令牌可能更简单,以便以更通用的方式释放它们。
我的程序有问题,我从 strsep()
收到了一个分段错误,它是从 GDB 得到的,并且有错误消息
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] == '[=11=]') {
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] == '[=12=]') {
return 0;
}
if(strcasecmp(&commands[i], "") == 0) {
i--;
}
}
return 0;
}
但是现在我遇到了一个新问题,命令返回一个空数组,其中每个索引都超出范围。
编辑 2
我还应该澄清一下我正在尝试做的事情,所以本质上命令是 char* commands[100]
类型的,我想将它传递给函数,然后修改原始指针数组并存储说`" Hello World"' into commands[0] 然后我想在函数外修改这个值。
你对commands
的用法与函数原型不一致:调用者传递了一个100的数组char*
,commands
应该是一个指向[=14=的数组的指针],因此类型 char **commands
或 char *commands[]
。为了让调用者确定存储在数组中的令牌数量,您应该在末尾存储一个 NULL
指针或 return 这个数字或两者。
存储 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 == '[=10=]') // ignore empty tokens
continue;
commands[i++] = token;
}
commands[i] = NULL;
if (i == 0) {
free(dup);
}
return i;
}
可以通过释放 commands
数组中的第一个指针来释放为令牌分配的内存。复制这些令牌可能更简单,以便以更通用的方式释放它们。