简体   繁体   English

GNU readline:巨大的内存泄漏

[英]GNU readline: enormous memory leak

Consider the following snippet: 请考虑以下代码段:

#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>

int main() {
    for (;;) {
        char *buf = readline(">>> ");
        if (!buf)
            break;

        free(buf);
    }
}

Compiling with -lreadline , executing the program under valgrind and inputting some lines result in an enormous memory leak, on my system valgrinds verdict looks something like this: 使用-lreadline编译,在valgrind下执行程序并输入一些行会导致巨大的内存泄漏,在我的系统上,valgrinds判断看起来像这样:

==7651== LEAK SUMMARY:
==7651==    definitely lost: 0 bytes in 0 blocks
==7651==    indirectly lost: 0 bytes in 0 blocks
==7651==      possibly lost: 0 bytes in 0 blocks
==7651==    still reachable: 213,455 bytes in 217 blocks
==7651==         suppressed: 0 bytes in 0 blocks

Running with --show-leak-kinds=all results something like this (the whole thing is several hundred lines long, I'll only show the beginning): 运行--show-leak-kinds=all结果都是这样的(整个事情是几百行,我只会显示开头):

==7693== 5 bytes in 1 blocks are still reachable in loss record 1 of 57
==7693==    at 0x483777F: malloc (vg_replace_malloc.c:299)
==7693==    by 0x48CE409: xmalloc (in /usr/lib/libreadline.so.8.0)
==7693==    by 0x48A72E6: rl_set_prompt (in /usr/lib/libreadline.so.8.0)
==7693==    by 0x48A87E6: readline (in /usr/lib/libreadline.so.8.0)
==7693==    by 0x10915C: main (in /home/.../a.out)
==7693== 
==7693== 5 bytes in 1 blocks are still reachable in loss record 2 of 57
==7693==    at 0x483777F: malloc (vg_replace_malloc.c:299)
==7693==    by 0x48CE409: xmalloc (in /usr/lib/libreadline.so.8.0)
==7693==    by 0x48B95BC: ??? (in /usr/lib/libreadline.so.8.0)
==7693==    by 0x48B9D25: rl_expand_prompt (in /usr/lib/libreadline.so.8.0)
==7693==    by 0x48A7309: rl_set_prompt (in /usr/lib/libreadline.so.8.0)
==7693==    by 0x48A87E6: readline (in /usr/lib/libreadline.so.8.0)
==7693==    by 0x10915C: main (in /home/.../a.out)
==7693== 
==7693== 8 bytes in 1 blocks are still reachable in loss record 3 of 57
==7693==    at 0x483777F: malloc (vg_replace_malloc.c:299)
==7693==    by 0x496C49E: strdup (in /usr/lib/libc-2.28.so)
==7693==    by 0x4AEEDCD: _nc_trim_sgr0 (in /usr/lib/libncursesw.so.6.1)
==7693==    by 0x4AE7EA2: tgetent_sp (in /usr/lib/libncursesw.so.6.1)
==7693==    by 0x48C39BC: _rl_init_terminal_io (in /usr/lib/libreadline.so.8.0)
==7693==    by 0x48A851C: rl_initialize (in /usr/lib/libreadline.so.8.0)
==7693==    by 0x48A87EC: readline (in /usr/lib/libreadline.so.8.0)
==7693==    by 0x10915C: main (in /home/.../a.out)

Now despite the fact that the memory is not lost, the fact that readline simply does not free huge chunks of memory before program exit seems completely absurd to me. 现在尽管内存没有丢失,但readline在程序退出之前根本没有释放大量内存这一事实对我来说似乎完全荒谬。 Am I missing something? 我错过了什么吗? Should I manually call some poorly documented cleanup functions? 我应该手动调用一些记录不完整的清理功能吗? Is this a bug? 这是一个错误吗? Does this occur on every system? 这是否发生在每个系统上?

There seem to be several similar issues floating around the Internet but I was surprised to see that this happens even in the simplest possible use case. 互联网上似乎有几个类似的问题,但我很惊讶地发现即使在最简单的用例中也会发生这种情况。

EDIT: because there has been a lot of discussion I will clarify a little: bruno's answer is of course correct, it's not a memory leak in the traditional sense and on almost all platforms it won't matter at all (I included the Linux tag, which was a mistake, I have removed it now), but I'd still like to know if this is really intentional or if happens because the memory is freed only after valgrind produces its statistics and if there is any way to get around this (or at the very least make valgrind ignore it so that it does not obscure missing free calls in the rest of my code) 编辑:因为有很多讨论我会澄清一点:布鲁诺的回答当然是正确的,它不是传统意义上的内存泄漏,几乎在所有平台上都没关系(我包括Linux标签) ,这是一个错误,我现在已经将其删除了),但是我仍然想知道这是否真的是故意的,或者是否因为只有在valgrind产生统计数据后才释放内存,并且有任何方法可以解决这个问题(或者至少让valgrind忽略它,这样它就不会掩盖其余代码中缺少的free调用)

GNU readline: enormous memory leak GNU readline:巨大的内存泄漏

 ==7651== LEAK SUMMARY: ==7651== definitely lost: 0 bytes in 0 blocks ==7651== indirectly lost: 0 bytes in 0 blocks ==7651== possibly lost: 0 bytes in 0 blocks 

There is no memory leak 没有内存泄漏

 ==7651== still reachable: 213,455 bytes in 217 blocks ==7651== suppressed: 0 bytes in 0 blocks ... 

A reachable memory is not a memory leak 可达内存不是内存泄漏

 ==7693== 5 bytes in 1 blocks are still reachable in loss record 1 of 57 ==7693== at 0x483777F: malloc (vg_replace_malloc.c:299) ==7693== by 0x48CE409: xmalloc (in /usr/lib/libreadline.so.8.0) ==7693== by 0x48A72E6: rl_set_prompt (in /usr/lib/libreadline.so.8.0) ==7693== by 0x48A87E6: readline (in /usr/lib/libreadline.so.8.0) ==7693== by 0x10915C: main (in /home/.../a.out) ... 

getline used memory and still references it, do not forget it manages a history, and the history can be freed calling void rl_clear_history (void) , add that function call in your program and redo a test getline使用内存并仍然引用它,不要忘记它管理历史记录,并且可以释放历史记录调用void rl_clear_history (void) ,在程序中添加该函数调用并重做测试

 Function: void rl_clear_history (void) Clear the history list by deleting all of the entries, in the same manner as the History library's clear_history() function. This differs from clear_history because it frees private data Readline saves in the history list. 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM