使用getline逐行读取文件时内存泄漏
memory leak when reading file line by line using getline
我正在使用 getline 逐行读取文件。 Valgrind 告诉我内存泄漏,我不确定我没有释放哪些 malloc 内存。
编辑:为了回应我想澄清的评论:我无法在没有从 valgrind 收到错误消息的情况下释放 "token" 变量,但我可以释放 "line" 变量,它我现在在循环之后做(见下面的代码)。尽管我在循环末尾有 "free(line)",但我仍然从 valgrind 收到内存泄漏消息。在循环内添加 "free(line)" 并不能解决这个问题。
我本质上是从文件中读取文本行,然后将该行中的相关信息分配给结构。相关代码为:
struct initial_data_params s_ID = {} ;
char* line = NULL ;
char* token = NULL ;
size_t len = 0 ;
ssize_t read = 0 ;
FILE* pf_initial_data = fopen(fN_initial_data, "r") ;
while ((read = getline(&line, &len, pf_initial_data)) != -1) {
token = strsep(&line, "=") ;
if ((token != NULL) && (strcmp(token, "r2Exp_amp") ==0)) {
token = strsep(&line, "=") ;
if (token != NULL) {
s_ID.r2Exp_amp = strtod(token, NULL) ;
}
}
(do something like this 9 more times for 9 other paramters)
}
fclose(pf_initial_data) ;
free(line) ;
line = NULL ;
return s_ID ;
Valgrind 告诉我
内存泄漏
while ((read = getline(&line, &len, pf_initial_data)) != -1)
特别是它在那一行说
==172360== 1,200 bytes in 10 blocks are definitely lost in loss record 57 of 58
==172360== at 0x4C29BC3: malloc (vg_replace_malloc.c:299)
==172360== by 0x5CE0744: getdelim (in /usr/lib64/libc-2.17.so)
==172360== by 0x416321: read_initial_data (file_io.c:38)
==172360== by 0x402FA4: main (main.c:14)
我应该补充:如果你认为有一种更好的方法来逐行读取文件并从c中的那一行中挑选出特定的string/character数组与使用 getline 相比,我也很乐意看到这一点。
您必须释放 getline 返回的内存。来自 man(3) getline:
If *lineptr is set to NULL and *n is set 0 before the call, then
getline() will allocate a buffer for storing the line. This buffer
should be freed by the user program even if getline() failed.
根据这个link:http://man7.org/linux/man-pages/man3/getline.3.html
如果给定缓冲区中没有足够的内存用于新行,函数 getline 将使用 realloc 为新行分配新内存。
在你的例子中,你已经将 char* line 初始化为 NULL,这意味着 getline 函数将找不到 space 为新行,并为其分配新内存。因此,您需要在停止使用后释放该线路。
fclose(pf_initial_data);
free(line); //simply add this line
return s_ID;
我正在使用 getline 逐行读取文件。 Valgrind 告诉我内存泄漏,我不确定我没有释放哪些 malloc 内存。
编辑:为了回应我想澄清的评论:我无法在没有从 valgrind 收到错误消息的情况下释放 "token" 变量,但我可以释放 "line" 变量,它我现在在循环之后做(见下面的代码)。尽管我在循环末尾有 "free(line)",但我仍然从 valgrind 收到内存泄漏消息。在循环内添加 "free(line)" 并不能解决这个问题。
我本质上是从文件中读取文本行,然后将该行中的相关信息分配给结构。相关代码为:
struct initial_data_params s_ID = {} ;
char* line = NULL ;
char* token = NULL ;
size_t len = 0 ;
ssize_t read = 0 ;
FILE* pf_initial_data = fopen(fN_initial_data, "r") ;
while ((read = getline(&line, &len, pf_initial_data)) != -1) {
token = strsep(&line, "=") ;
if ((token != NULL) && (strcmp(token, "r2Exp_amp") ==0)) {
token = strsep(&line, "=") ;
if (token != NULL) {
s_ID.r2Exp_amp = strtod(token, NULL) ;
}
}
(do something like this 9 more times for 9 other paramters)
}
fclose(pf_initial_data) ;
free(line) ;
line = NULL ;
return s_ID ;
Valgrind 告诉我
内存泄漏while ((read = getline(&line, &len, pf_initial_data)) != -1)
特别是它在那一行说
==172360== 1,200 bytes in 10 blocks are definitely lost in loss record 57 of 58
==172360== at 0x4C29BC3: malloc (vg_replace_malloc.c:299)
==172360== by 0x5CE0744: getdelim (in /usr/lib64/libc-2.17.so)
==172360== by 0x416321: read_initial_data (file_io.c:38)
==172360== by 0x402FA4: main (main.c:14)
我应该补充:如果你认为有一种更好的方法来逐行读取文件并从c中的那一行中挑选出特定的string/character数组与使用 getline 相比,我也很乐意看到这一点。
您必须释放 getline 返回的内存。来自 man(3) getline:
If *lineptr is set to NULL and *n is set 0 before the call, then getline() will allocate a buffer for storing the line. This buffer should be freed by the user program even if getline() failed.
根据这个link:http://man7.org/linux/man-pages/man3/getline.3.html 如果给定缓冲区中没有足够的内存用于新行,函数 getline 将使用 realloc 为新行分配新内存。
在你的例子中,你已经将 char* line 初始化为 NULL,这意味着 getline 函数将找不到 space 为新行,并为其分配新内存。因此,您需要在停止使用后释放该线路。
fclose(pf_initial_data);
free(line); //simply add this line
return s_ID;