C-Lang:在 for 循环中使用字符串时出现分段错误

C-Lang: Segmentation Fault when working with string in for-loop

最近,在大学里,我们开始用C语言学习字符串,作为作业,我被布置了一个任务,编写一个去除多余单词的程序。

在编写程序时,我遇到了一个通过字符串迭代的问题,我可以用一种 hacky 的方式解决这个问题。但是,我想在你的帮助下解决这个问题,因为我自己找不到错误。

问题是当我使用 strlen(buffer) 函数作为 for 循环条件时,代码很容易编译并且在运行时没有错误,尽管当我使用 __act_buffer_len variable 时,它被赋值为 strlen(buffer) 在运行时会出现分段错误。

我尝试了很多方法来解决这个问题,但我已经描述过的唯一一种对我有用。

// deletes words with <= 2 letters
char* _delete_odd(const char* buffer, char delim)
{
    int __act_buffer_len = strlen(buffer);

    // for debugging purposes
    printf("__actbuff: %d\n", __act_buffer_len);
    printf("sizeof: %d\n", sizeof(buffer));
    printf("strlen: %d\n", strlen(buffer));

    char* _newbuff = malloc(__act_buffer_len + 1); // <- new buffer without words with less than 2 unique words
    char* _tempbuff; // <- used to store current word

    int beg_point = 0;
    int curr_wlen = 0;
    for (int i = 0; i < strlen(buffer); i++)       // no errors at runtime, app runs well
    // for (int i = 0; i < __act_buffer_len; i++)  // <- segmentation fault when loop is reaching a space character
    // for (int i = 0; buffer[i] != '[=10=]'; i++)     // <- also segmentation fault at the same spot
    // for (size_t i = 0; i < strlen(buffer); i++) // <- even this gives a segmentation fault which is totally confusing for me
    {
        printf("strlen in loop %d\n", i);
        if (buffer[i] == delim)
        {
            char* __cpy;
            memcpy(__cpy, &buffer[beg_point], curr_wlen); // <- will copy a string starting from the beginning of the word til its end

            // this may be commented for testing purposes
            __uint32_t __letters = __get_letters(__cpy, curr_wlen); // <- will return number of unique letters in word
            if (__letters > 2) // <- will remove all the words with less than 2 unique letters
            {
                strcat(_newbuff, __cpy);
                strcat(_newbuff, " ");
            }

            beg_point = i + 1; // <- will point on the first letter of the word
            curr_wlen = buffer[beg_point] == ' ' ? 0 : 1; // <- if the next symbol after space is another space, than word length should be 0
        } 
        else curr_wlen++;
    }
    return _newbuff;
}

简而言之,上面的代码只是在字符串中找到分隔符,并计算该分隔符之前的单词的唯一字母数。

我的错是没有初始化 __cpy 变量。 另外,正如 @n.1.8e9-where's-my-sharem. 所述,我不应该用两个下划线命名变量。

最终代码:

// deletes words with <= 2 letters
char* _delete_odd(const char* buffer, char delim)
{
    size_t _act_buffer_len = strlen(buffer);
    char* _newbuff = malloc(_act_buffer_len); // <- new buffer without words with less than 2 unique words

    int beg_point = 0;
    int curr_wlen = 0;
    for (size_t i = 0; i < _act_buffer_len; i++)
    {
        if (buffer[i] == delim)
        {
            char* _cpy = malloc(curr_wlen);
            memcpy(_cpy, &buffer[beg_point], curr_wlen); // <- will copy a string starting from the beginning of the word til its end

            // this may be commented for testing purposes
            __uint32_t _letters = _get_letters(_cpy, curr_wlen); // <- will return number of unique letters in word
            if (_letters > 2) // <- will remove all the words with less than 2 unique letters
                strcat(_newbuff, _cpy);

            beg_point = i + 1; // <- will point on the first letter of the word
            curr_wlen = buffer[beg_point] == ' ' ? 0 : 1; // <- if the next symbol after space is another space, than word length should be 0

            free(_cpy);
        } 
        else curr_wlen++;
    }
    return _newbuff;
}

谢谢你帮助我