【发布时间】:2018-12-22 07:31:57
【问题描述】:
问题
我目前正在为 Windows 编写一个类似于 grep 的小型(和糟糕的)程序。在其中我想逐行读取文件并打印出包含密钥的文件。为此,我需要一个读取文件每一行的函数。由于我不在 Linux 上,我无法使用 getline 函数,必须自己实现。
我找到了一个 SO answer 实现了这样的功能。我试过了,它适用于“普通”文本文件。但是,如果我尝试读取行长为 13 000 个字符的文件,程序就会崩溃。
MCVE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char * getline(FILE *f)
{
size_t size = 0;
size_t len = 0;
size_t last = 0;
char *buf = NULL;
do {
size += BUFSIZ; /* BUFSIZ is defined as "the optimal read size for this platform" */
buf = realloc(buf, size); /* realloc(NULL,n) is the same as malloc(n) */
/* Actually do the read. Note that fgets puts a terminal '\0' on the
end of the string, so we make sure we overwrite this */
if (buf == NULL) return NULL;
fgets(buf + last, size, f);
len = strlen(buf);
last = len - 1;
} while (!feof(f) && buf[last] != '\n');
return buf;
}
int main(int argc, char *argv[])
{
FILE *file = fopen(argv[1], "r");
if (file == NULL)
return 1;
while (!feof(file))
{
char *line = getline(file);
if (line != NULL)
{
printf("%s", line);
free(line);
}
}
return 0;
}
这是我正在使用的file。它包含三行可以很好阅读的短行和我的一个 Qt 项目中的长行。读取此行时,getline 函数将 2 次重新分配到 1024 的大小,并在第 3 次崩溃。我在realloc 周围加上了printf,以确保它在那里崩溃并且确实如此。
问题
谁能解释一下为什么我的程序会这样崩溃?我只是花几个小时在这上面,不知道该怎么办了。
【问题讨论】:
-
你 add
size + BUFSIZ并分配它,但随后你 读取 一样 - 增加了! –size。从本质上讲,您阅读的字符数比您在每一回合中分配的字符数越来越多。如果您只阅读BUFSIZE,那么这应该可以。 -
你不检查
fgets()是否失败... -
@usr2564301 谢谢!我可以发誓我已经尝试过这个,因为它对我来说也没有多大意义。随时发布答案,我会接受。干杯。
-
关于:
buf = realloc(buf, size);调用realloc()时,始终将返回值保存到“temp”变量中,检查“temp”变量,只有在不为NULL 时才复制到目标变量。否则,当realloc()失败时,分配内存的指针丢失,导致内存泄漏是结果