尝试访问正确分配的数组时出现分段错误
Segmentation fault when trying to access properly allocated array
我正在尝试读取一个 CSV 文件并正在编写一个函数来将一行数据解析为一个字符串数组,它会动态更改数组的大小并更新 size
和 str_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
,以免
他想要一个段错误。
我正在尝试读取一个 CSV 文件并正在编写一个函数来将一行数据解析为一个字符串数组,它会动态更改数组的大小并更新 size
和 str_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
,以免
他想要一个段错误。