字符串分割函数中的分段错误

时间:2017-05-26 08:22:47

标签: c gcc

我不确定我的代码有什么问题:

#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])。为什么会触发分段错误?我只是将字符串中的一个字符更改为另一个字符!

2 个答案:

答案 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]