使用getline逐行读取文件时发生内存泄漏

时间:2019-04-17 15:26:53

标签: c file-io memory-leaks

我正在使用getline逐行读取文件。 Valgrind告诉我我遇到了内存泄漏,并且我不确定我没有释放的是什么已分配的内存。

编辑:针对我想澄清的评论:我无法在没有收到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)

我应该补充一点:如果您认为有一种更好的方式,可以比使用getline逐行读取文件并从该行中选择特定的字符串/字符数组,我会也很高兴看到这一点。

2 个答案:

答案 0 :(得分:3)

您必须释放getline返回的内存。来自man(3)getline:

  

如果在调用之前将* lineptr设置为NULL并将* n设置为0,则   getline()将分配一个缓冲区来存储行。这个缓冲区   即使getline()失败,用户程序也应释放它。

答案 1 :(得分:0)

根据此链接:http://man7.org/linux/man-pages/man3/getline.3.html 如果给定缓冲区中的新行没有足够的内存,则功能 getline 将使用realloc为新行分配新的内存。

在您的情况下,您已将 char *行初始化为NULL,这意味着 getline 函数将找不到新行的空间,并将分配一个新行。新的记忆。因此,您需要在停止使用该行后释放它。

fclose(pf_initial_data);
free(line);    //simply add this line
return s_ID;