尝试访问正确分配的数组时出现分段错误

Segmentation fault when trying to access properly allocated array

我正在尝试读取一个 CSV 文件并正在编写一个函数来将一行数据解析为一个字符串数组,它会动态更改数组的大小并更新 sizestr_size 相应地。我已经编写了一个名为 find_key() 的正常工作函数来定位相关行的 fseek() 位置。我遇到了一个我认为与字符串数组分配有关的问题:我在 while 循环底部的行上遇到了分段错误,它显示为 data[data_count][str_pos] = curr。当我尝试访问 data[0][0] 时程序中断,尽管据我所知我已经正确分配了内存。如有任何帮助,我们将不胜感激!

/**
 * @brief Get a row from the provided CSV file by first item. Dynamically
 *        allocated memory to data array
 * 
 * @param file
 * @param key First item of row
 * @param data Array of strings containing data
 * @param size Size of array
 * @param str_size Size of strings in array
 * @return 0 if successful, -1 if the row cannot be found, or 1 otherwise
 */
int csv_get_row(FILE *file, char *key, char **data, size_t *size, size_t *str_size) {
    if(!file || !key) return 1;

    /* Get the position of the beginning of the line starting with the key */
    long pos = find_key(file, key);
    if(pos == -1) return -1;
    fseek(file, pos, SEEK_SET);

    /* If these parameters aren't useful values, assign default values */
    if(*size < 1) *size = DEFAULT_ARRAY_SIZE;
    if(*str_size < 1) *str_size = DEFAULT_BUFFER_SIZE;

    /* If the memory for the array hasn't been allocated, do so now */
    if(!data) data = (char**) malloc(*size * *str_size);

    /* Get characters one-by-one, keeping track of the current amount of elements and the current buffer position */
    size_t data_count = 0;
    size_t str_pos = 0;
    char curr;
    while(fscanf(file, "%c", &curr)) {
        if(data_count >= *size) data = (char**) realloc(data, (*size *= 2) * *str_size);
        if(str_pos >= *str_size) data = (char**) realloc(data, *size * (*str_size *= 2));

        if(curr == ',') {
            data[data_count][str_pos] = '[=10=]';
            data_count++;
            str_pos = 0;
            continue;
        }

        if(curr == '\n') {
            data[data_count][str_pos] = '[=10=]';
            data_count++;
            break;
        }

        data[data_count][str_pos] = curr;
        str_pos++;
    }

    /* Resize the array to fit */
    *size = data_count;
    data = (char**) realloc(data, *size * *str_size);
    return 0;
}

假设 *size 从 1 开始。您将 data_count 设置为 0。然后,在第一次迭代中, 你没有 data_count >= *size,所以你没有 realloc()。你递增 data_count 但是,到 1,所以在下一次迭代中,您将 data 缓冲区增加到 2.

因此,此时 data 的长度为 2,data_count 的长度为 1。

那么假设我们不进入第一个 if 语句,而是进入第二个。 在那里,您将 data_count 增加到 2。然后你访问 data[data_count],这是一个 过去的最后一个元素。那是个问题。

这可能是您在 while 循环末尾看到的问题,但它远非 唯一的问题。每当您 malloc()realloc() data 时,您都在使调用者的指针无效 有,因为您可能会在原始位置释放内存。你从不给他 指向新数据的指针;当您 return 来自函数,调用者必须 never 在调用后访问 data,以免 他想要一个段错误。