【问题标题】:Segmentation fault on calling function more then once多次调用函数时出现分段错误
【发布时间】:2013-05-19 04:34:21
【问题描述】:

多次运行此函数将导致分段错误,我无法弄清楚原因。我不是在寻找分割字符串的替代方法。

SplitX 将继续拆分 x 数量的分隔符(无论是 '|' 还是 '\0')并返回 x 或它可以生成的子字符串的数量。

我应该注意,在使用了 3 年简单的 JavaScript 和 PHP 之后,我刚刚重新开始用 C 编码,所以我可能会遗漏一些明显的东西。

int splitX(char **array, char *string, int x) {
    int y;
    int z;
    int index = 0;
    int windex = 0;
    for(y = 0; y < x; y++) {
        z = index;
        while(string[index] != '\0' && string[index] != '|') {
            index++;
        }
        char **tempPtr = realloc(array, (y+1)*sizeof(char *));
        if(tempPtr == NULL) {
            free(array);
            return -3;
        }
        array = tempPtr;
        array[y] = malloc(sizeof(char) * (index - z + 1));
        windex = 0;
        for(; z < index; z++) {
            array[y][windex] = string[z];
            windex++;
        }
        array[y][windex] = '\0';
        if(string[index] == '\0')
            break;
        index++;
    }
    return y+1;
}

int main() {
        char **array;
        int array_len = splitX(array, query, 2);
        printf("%s %s %d\n", array[0], array[1], array_len);
        while(array_len > 0) {
            free(array[array_len-1]);
            array_len--;
        }
        free(array);
        array_len = splitX(array, "1|2\0", 2);
        printf("%s %s %d\n", array[0], array[1], array_len);
        while(array_len > 0) {
            free(array[array_len-1]);
            array_len--;
        }
        free(array);
}

【问题讨论】:

    标签: c string segmentation-fault


    【解决方案1】:
    char **array;
    int array_len = splitX(array, query, 2);
    

    这让splitX() 使用未初始化的array,从而导致未定义的行为。

    此外,C 没有传递引用 - 当您编写时

     array = tempPtr;
    

    在函数内部,外部没有可见的效果。

    我不是在寻找分割字符串的替代方法。

    你真的应该是。您当前的方法充其量是非惯用的,但它也有一些其他错误(例如由于某种原因返回y + 1y 肯定会这样做,等等)。

    您也在重新发明轮子:对于字符串和字符搜索,请使用 C 标准库中的 strstr()strchr()strtok_r();对于复制字符串,请使用strdup() 而不是手动遍历字符串等...

    还有什么:

    • 使用size_t 代替int

    • 通过对输入字符串使用const char * 来保持 const 的正确性。


    char **split(const char *s, size_t *sz)
    {
        char **r = NULL;
        size_t n = 0, allocsz = 0;
        const char *p = s, *t = p;
        int end = 0;
    
        do {
            const char *tmp = strchr(p, '|');
            if (tmp == NULL) {
                p = p + strlen(p);
                end = 1;
            } else {
                p = tmp;
            }
    
            if (++n > allocsz) {
                if (allocsz == 0)
                    allocsz = 4;
                else
                    allocsz <<= 1;
    
                char **tmp = realloc(r, sizeof(*r) * allocsz);
                if (!tmp) abort(); // or whatever, handle error
                r = tmp;
            }
    
            r[n - 1] = malloc(p - t + 1);
            memcpy(r[n - 1], t, p - t);
            r[n - 1][p - t] = 0;
    
            p++;
            t = p;
        } while (!end);
    
        *sz = n;
        return r;
    }
    

    【讨论】:

    • array = tempPtr 不传递已分配的内存地址吗? *array = valuearray=address
    • @Gaby_64 C 没有通过引用。
    猜你喜欢
    • 2018-05-04
    • 2011-01-08
    • 1970-01-01
    • 2020-08-04
    • 2018-12-15
    • 1970-01-01
    相关资源
    最近更新 更多