我不确定我的代码有什么问题:
#include <stdio.h>
#include <string.h>
char* splitstr(char* str, int part, char search) {
char* out;
int i;
int result = 0;
for(i=0; str[i]!='\0'; i++) {
if(str[i] == search) {
result = 1;
break;
}
}
if(result == 0) {
if(part == 1) {
return str;
} else {
return "";
}
}
int j;
int k;
if(part == 2) {
for(j = 0; j < i; j++) {
out[j] = str[j];
}
out[j] = '\0';
} else {
for(k = 0,j = i+1; j <= strlen(str)-1; j++, k++) {
out[k] = str[j];
}
out[k] = '\0';
}
return out;
}
}
int main() {
printf("Starting program:\n");
char* str = "Hello World!";
char* a = splitstr(str, 1, ' ');
char* b = splitstr(str, 1, ' ');
printf("A is %s\n", a);
printf("B is %s\n", b);
}
返回以下输出:
Starting program:
Segmentation Fault: 11
使用gdb
进行调试后,我发现在第30行(通过使用断点)发生错误,在第一次循环迭代时,它尝试设置out[0]
({{ 1}})到out[k]
(str[6]
)。为什么会触发分段错误?我只是将字符串中的一个字符更改为另一个字符!
答案 0 :(得分:6)
out
中没有字符串。它是一个未初始化的指针,因为没有为您的写入分配内存,所以您无法通过它进行写入。这样做会触发未定义的行为,这就是程序崩溃的原因。
您必须分配一些,通常使用malloc()
。
另外,仅作为评论类型的注释,第一个循环相当于:
const int result = strchr(str, search) != NULL;
答案 1 :(得分:0)
主要问题是这一行:
char* out;
仅声明一个指针,但不会将该指针设置为指向任何特定内存(应用程序拥有)
所以这一行:
out[j] = str[j];
将值分配给内存中的某个随机位置。
通过以下方式解决问题:
char *out[ strlen( str ) +1 ]; // uses variable length array feature
或通过:
char *out = malloc( strlen(str) +1 );
if( !out )
{ // malloc failed
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
你的编译器应该通过如下语句告诉你这个问题:
filename.c:43:16: warning: 'out' may be used uninitialized in this function [-Wmaybe-uninitialized]
编译时,始终启用警告,然后修复这些警告。
(对于gcc
,至少使用:-Wall -Wextra -pedantic
我还使用:-Wconversion -std=gnu11
)
如果使用-Wconversion
选项,则编译器也会输出:
filename.c:51:30: warning: comparison between signed and unsigned integer expression [-Wsign-compare]