[英]Seg fault when reading a line into dynamically allocated char pointer array
In C, I am trying to implement a function that uses getline()
to read all the lines from a file. 在C语言中,我试图实现一个使用
getline()
从文件读取所有行的函数。 It is implemented similarly to getline()
, specifically the fact that it is using realloc()
to resize a char**
if there is not enough memory allocated to store the next pointer to a line. 它的实现与
getline()
类似,特别是以下事实:如果没有足够的内存分配来存储指向行的下一个指针,它将使用realloc()
来调整char**
大小。 Unfortunately I am getting seg faults during the string dupilcation process. 不幸的是,在字符串复制过程中出现段错误。
After a little poking around, I discovered that the segfault happens during the second iteration while attempting to store the second line in the char pointer array. 经过一番摸索之后,我发现该段错误发生在第二次迭代中,同时尝试将第二行存储在char指针数组中。
ssize_t fgetlines(char*** linesptr, size_t* n, FILE* fp)
{
char* line = NULL;
size_t sz_line = 0;
size_t cur_len = 0;
size_t needed;
if (linesptr == NULL || n == NULL) {
errno = EINVAL;
return -1;
}
if (*linesptr == NULL) {
if (*n == 0)
*n = sizeof(**linesptr) * 30; /* assume 30 lines */
*linesptr = malloc(*n);
if (*linesptr == NULL) {
*n = 0;
return -1;
}
}
while (getline(&line, &sz_line, fp) > 0) {
needed = (cur_len + 1) * sizeof(**linesptr);
while (needed > *n) {
char** new_linesptr;
*n *= 2;
new_linesptr = realloc(*linesptr, *n);
if (new_linesptr == NULL) {
*n /= 2;
free(line);
return -1;
}
*linesptr = new_linesptr;
}
*linesptr[cur_len] = strdup(line);
printf("%s", *linesptr[cur_len]);
if (*linesptr[cur_len] == NULL) {
free(line);
free(*linesptr);
return -1;
}
++cur_len;
}
free(line);
return cur_len;
}
And I call the function like so: 我这样调用该函数:
char **settings = NULL;
size_t sz_settings = sizeof(*settings) * 6;
int count = fgetlines(&settings, &sz_settings, f_cfg);
Due to the function not being able to successfully complete I do not get any output. 由于该功能无法成功完成,因此我没有任何输出。 But after printing back the string after
strdup()
I managed to get one line of f_cfg
, "Hello World"
before a seg fault. 但是在
strdup()
之后打印回字符串之后,我设法在段错误之前获得了f_cfg
一行"Hello World"
。
As chux pointed out, the intended precedence here was incorrect. 正如chux所指出的,此处的预期优先级是不正确的。 References to
*linesptr[cur_len]
must be changed to (*linesptr[cur_len])
. 对
*linesptr[cur_len]
引用必须更改为(*linesptr[cur_len])
。 Also the code hole *n == 0 and *n *= 2
has been fixed. 代码孔
*n == 0 and *n *= 2
也已修复。
Should change 应该改变
*linesptr[cur_len] => (*linesptr)[cur_len]
The modified function is as follows: 修改后的功能如下:
ssize_t fgetlines(char *** linesptr, size_t *n, FILE *fp)
{
char *line = NULL;
size_t sz_line = 0;
size_t cur_len = 0;
size_t needed;
if (linesptr == NULL || n == NULL) {
errno = EINVAL;
return -1;
}
if (*linesptr == NULL) {
if (*n == 0)
*n = sizeof(**linesptr) * 30; /* assume 30 lines */
*linesptr = malloc(*n);
if (*linesptr == NULL) {
*n = 0;
return -1;
}
}
while (getline(&line, &sz_line, fp) > 0) {
needed = (cur_len + 1) * sizeof(**linesptr);
while (needed > *n) {
char **new_linesptr;
*n *= 2;
new_linesptr = realloc(*linesptr, *n);
if (new_linesptr == NULL) {
*n /= 2;
free(line);
return -1; // Possible memory leak
}
*linesptr = new_linesptr;
}
(*linesptr)[cur_len] = strdup(line);
printf("%s", (*linesptr)[cur_len]);
if ((*linesptr)[cur_len] == NULL) {
free(line);
free(*linesptr);
return -1; // Possible memory leak
}
++cur_len;
}
free(line);
return cur_len;
}
In addition, when your memory allocation fails, the memory of "strdup" is not free, which will lead to memory leak. 另外,当您的内存分配失败时,“ strdup”的内存不是空闲的,这将导致内存泄漏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.