考虑以下代码段:
#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:巨大的内存泄漏
Run Code Online (Sandbox Code Playgroud)==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) ...
getline使用了内存并仍然引用它,不要忘记它管理一个历史记录,该历史记录可以被释放调用void rl_clear_history (void),在程序中添加该函数调用并重做测试
Run Code Online (Sandbox Code Playgroud)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.