内存泄漏:从文件中读取并返回行
Memory Leak: Reading and returning line from file
我正在尝试从文件中读取一行 return 该行。但是,我不断遇到内存泄漏,丢失了 4000 个字节,并且比 allocs 少了一个字节。我不知道为什么会这样。下面是函数。
char *readLine(FILE *input, int lineNum) {
char *string = calloc(MAX_LEN, sizeof(char));
rewind(input);
char *check = fgets(string, MAX_LEN, input);
int stringLength = strlen(string);
if (stringLength > MAX_LEN) {
printf("Line too long to stdout.");
free(string);
return EXIT_SUCCESS;
} else
if (check == NULL) {
free(string);
return NULL;
}
return string;
}
我是这样称呼它的:
char *line = readLine(input, 0);
注意:忽略lineNum
的东西,我会在解决内存泄漏后加入。
那么,内存泄漏的原因和位置在哪里?详尽的解释将非常有帮助。谢谢大家!
编辑: 这是调用 readLine()
的函数:
char *makeSummary(FILE *input, int summaryNum) {
char *line = readLine(input, 0); //Get first line
int lineLength = strlen(line);
if (summaryNum == 1) {
//Get the last line of file by looping till NULL
lineNum = 10;
line = readLine(input, lineNum);
//Do more stuff with line
}
free(line);
}
您的函数在需要 return 时不会 free(string)
(这是有道理的),因此除非您未发布的部分代码是 free
-查看它(由于显而易见的原因,这里的任何人都无法分辨),这就是你的漏洞。
谢谢大家,特别是@WhozCraig。问题在于使用 readLine 的函数在实际读取所需的行号之前没有释放 Line。现在已修复此问题,一切正常。
您的代码存在一些问题:
在函数 readLine
中,您在测试 check == NULL
之前计算 string
的长度。这可能是不正确的。
另外,string
的长度根据定义小于MAX_LEN
,你测试总是假的。您可能需要检查该行是否以换行符结尾以检测截断。
你returnEXIT_SUCCESS
,但是函数return是char *
。编译器不会检测到这种差异,因为 EXIT_SUCCESS
定义为 0
,因此 return EXIT_SUCCESS;
与 return NULL;
.
相同
在函数 makeSummary
中,您似乎用指针 return 覆盖了 line
并在下一次调用 readLine()
时被修改。您必须在line = readLine(input, 0)
之前调用free(line);
。
你在readLine()
中调用了rewind()
,所以你一直从输入文件中读取同一行,除非文件不能被查找(比如终端),如果你正在从一个普通文件中读取,你永远不会读完。
这是分配更少字节的修改版本:
char *readLine(FILE *input, int lineNum) {
char buf[MAX_LEN];
size_t len;
if (!fgets(buf, sizeof(buf), input)) {
return NULL;
}
if ((len = strlen(buf)) == MAX_LEN - 1 && buf[len - 1] != '\n') {
printf("Line too long from file.");
return NULL;
}
return strdup(buf);
}
char *makeSummary(FILE *input, int summaryNum) {
char *line = readLine(input, 0); //Get first line
if (line == NULL)
return NULL;
int lineLength = strlen(line);
if (summaryNum == 1) {
//Get the last line of file by looping till NULL
lineNum = 10;
free(line);
line = readLine(input, lineNum);
//Do more stuff with line
}
free(line);
return NULL;
}
请注意,strdup()
不是标准的,在非 Posix 系统上可能不可用,但很容易实现:
#include <string.h>
char *strdup(const char *s) {
size_t size = strlen(s) + 1;
char *p = malloc(size);
if (p != NULL) {
memcpy(p, s, size);
}
return p;
}
我正在尝试从文件中读取一行 return 该行。但是,我不断遇到内存泄漏,丢失了 4000 个字节,并且比 allocs 少了一个字节。我不知道为什么会这样。下面是函数。
char *readLine(FILE *input, int lineNum) {
char *string = calloc(MAX_LEN, sizeof(char));
rewind(input);
char *check = fgets(string, MAX_LEN, input);
int stringLength = strlen(string);
if (stringLength > MAX_LEN) {
printf("Line too long to stdout.");
free(string);
return EXIT_SUCCESS;
} else
if (check == NULL) {
free(string);
return NULL;
}
return string;
}
我是这样称呼它的:
char *line = readLine(input, 0);
注意:忽略lineNum
的东西,我会在解决内存泄漏后加入。
那么,内存泄漏的原因和位置在哪里?详尽的解释将非常有帮助。谢谢大家!
编辑: 这是调用 readLine()
的函数:
char *makeSummary(FILE *input, int summaryNum) {
char *line = readLine(input, 0); //Get first line
int lineLength = strlen(line);
if (summaryNum == 1) {
//Get the last line of file by looping till NULL
lineNum = 10;
line = readLine(input, lineNum);
//Do more stuff with line
}
free(line);
}
您的函数在需要 return 时不会 free(string)
(这是有道理的),因此除非您未发布的部分代码是 free
-查看它(由于显而易见的原因,这里的任何人都无法分辨),这就是你的漏洞。
谢谢大家,特别是@WhozCraig。问题在于使用 readLine 的函数在实际读取所需的行号之前没有释放 Line。现在已修复此问题,一切正常。
您的代码存在一些问题:
在函数
readLine
中,您在测试check == NULL
之前计算string
的长度。这可能是不正确的。另外,
string
的长度根据定义小于MAX_LEN
,你测试总是假的。您可能需要检查该行是否以换行符结尾以检测截断。你return
EXIT_SUCCESS
,但是函数return是char *
。编译器不会检测到这种差异,因为EXIT_SUCCESS
定义为0
,因此return EXIT_SUCCESS;
与return NULL;
. 相同
在函数
makeSummary
中,您似乎用指针 return 覆盖了line
并在下一次调用readLine()
时被修改。您必须在line = readLine(input, 0)
之前调用free(line);
。你在
readLine()
中调用了rewind()
,所以你一直从输入文件中读取同一行,除非文件不能被查找(比如终端),如果你正在从一个普通文件中读取,你永远不会读完。
这是分配更少字节的修改版本:
char *readLine(FILE *input, int lineNum) {
char buf[MAX_LEN];
size_t len;
if (!fgets(buf, sizeof(buf), input)) {
return NULL;
}
if ((len = strlen(buf)) == MAX_LEN - 1 && buf[len - 1] != '\n') {
printf("Line too long from file.");
return NULL;
}
return strdup(buf);
}
char *makeSummary(FILE *input, int summaryNum) {
char *line = readLine(input, 0); //Get first line
if (line == NULL)
return NULL;
int lineLength = strlen(line);
if (summaryNum == 1) {
//Get the last line of file by looping till NULL
lineNum = 10;
free(line);
line = readLine(input, lineNum);
//Do more stuff with line
}
free(line);
return NULL;
}
请注意,strdup()
不是标准的,在非 Posix 系统上可能不可用,但很容易实现:
#include <string.h>
char *strdup(const char *s) {
size_t size = strlen(s) + 1;
char *p = malloc(size);
if (p != NULL) {
memcpy(p, s, size);
}
return p;
}