问题描述
我的程序出现问题,我从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] == '\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 World时将其传递给函数“'放入commands [0],然后我要在函数外部修改此值。
解决方法
您对 private func constrainFloatingButtonToWindow() {
DispatchQueue.main.async {
guard let keyWindow = UIApplication.shared.windows.first(where: { $0.isKeyWindow }),let floatingButton = self.floatingButton else { return }
keyWindow.addSubview(floatingButton)
keyWindow.trailingAnchor.constraint(equalTo: floatingButton.trailingAnchor,constant: self.trailingValue).isActive = true
keyWindow.bottomAnchor.constraint(equalTo: floatingButton.bottomAnchor,constant: self.trailingValue).isActive = true
floatingButton.widthAnchor.constraint(equalToConstant:
DataTableViewController.buttonWidth).isActive = true
floatingButton.heightAnchor.constraint(equalToConstant:
DataTableViewController.buttonHeight).isActive = true
}
}
的使用与函数原型不一致:调用者传递的数组为100 commands
,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;
}
数组中的第一个指针来释放为令牌分配的内存。复制这些令牌可能更简单,以便以更通用的方式释放它们。