GNU readline:巨大的内存泄漏

Pet*_*ter 5 c gnu readline

考虑以下代码段:

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

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

        free(buf);
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的系统上,使用valgrinds进行编译-lreadline,在其下执行程序valgrind并输入一些行会导致巨大的内存泄漏,如下所示:

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

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

        free(buf);
    }
}
Run Code Online (Sandbox Code Playgroud)

运行--show-leak-kinds=all类似这样的结果(整个过程长数百行,我只显示开始):

==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
Run Code Online (Sandbox Code Playgroud)

现在,尽管内存没有丢失,但readline并没有在程序退出之前释放大量内存,这一事实对我来说完全是荒谬的。我想念什么吗?我应该手动调用一些记录较差的清理功能吗?这是错误吗?是否在每个系统上都发生?

互联网上似乎有一些类似的问题,但是令我惊讶的是,即使在最简单的用例中,这种情况也会发生。

编辑:因为已经进行了很多讨论,所以我将澄清一下:bruno的答案当然是正确的,这不是传统意义上的内存泄漏,并且在几乎所有平台上都没有关系(我包括Linux标签) ,这是一个错误,我现在已将其删除),但我仍然想知道这是否真的有意或是否会发生,因为仅在valgrind生成其统计信息之后才释放内存,并且是否有任何方法可以解决此问题(或至少使valgrind忽略它,以便它不会掩盖free我其余代码中的丢失调用)

bru*_*uno 12

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
Run Code Online (Sandbox Code Playgroud)

没有内存泄漏

==7651==    still reachable: 213,455 bytes in 217 blocks
==7651==         suppressed: 0 bytes in 0 blocks
...
Run Code Online (Sandbox Code Playgroud)

可达存储器是不是内存泄漏

==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)
...
Run Code Online (Sandbox Code Playgroud)

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.
Run Code Online (Sandbox Code Playgroud)

  • @StaceyGirl标题再次是关于(巨大的)内存泄漏,并且没有内存泄漏 (4认同)
  • 如果泄漏的内存量随输入大小的增加而增加,则可访问的内存也是内存泄漏。 (2认同)
  • 无关紧要的,随着输入线性增长的泄漏是泄漏,因为它最终会阻止进程工作。 (2认同)
  • @StaceyGirl的readline不像_gets_一样简单,它管理历史记录,因此_of_当然它使用内存来保存历史记录,如果您不需要,那就不要使用它;-) (2认同)
  • @StaceyGirl当然不是^^你读了我的答案吗? (2认同)