使用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;