Valgrind报告从stdin的getline后释放的指针上的内存泄漏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Valgrind报告从stdin的getline后释放的指针上的内存泄漏相关的知识,希望对你有一定的参考价值。

具有此代码:

#include <stdlib.h>
#include <stdio.h>
void main()
{   
    char *line = calloc(1024, 1);
    size_t size = 0;
    getline(&line, &size, stdin);
    free(line);
}

Valgrind抱怨:

==5931== HEAP SUMMARY:
==5931==     in use at exit: 1,024 bytes in 1 blocks
==5931==   total heap usage: 3 allocs, 2 frees, 2,168 bytes allocated
==5931== 
==5931== 1,024 bytes in 1 blocks are definitely lost in loss record 1 of 1
==5931==    at 0x4837B65: calloc (vg_replace_malloc.c:752)
==5931==    by 0x10916B: main (test.c:5)
==5931== 
==5931== LEAK SUMMARY:
==5931==    definitely lost: 1,024 bytes in 1 blocks

我看过其他相关文章,但找不到此特定情况的答案:/

答案

这是一个glibc错误(或长期存在的glibc行为,具体取决于您如何看待它:]

很难在glibc中修复,因为许多应用程序都假定在长度为零时不必像kluttoriginal reply那样初始化行指针。如果glibc开始释放或在零长度的情况下使用行指针,则将导致崩溃。

另一答案

getlinecalloc都分配内存。如果要使用getline,请不要预先分配。只需这样做:

int main(void)
{   
    char *line = NULL;
    size_t size = 0;
    getline(&line, &size, stdin);
    free(line);
}

此提示是您如何呼叫getline。如果发送line,则该函数将无法更改指针指向的内容。但是现在您正在发送&line,这表明该函数要重新分配内存。

如果要预分配,请使用fgets而不是getline

此外,main不应是void函数。

另一答案

size中包含的大小是line中保存的当前分配的大小。因此解决方法是

#include <stdlib.h>
#include <stdio.h>
int main(void)
{   
    char *line = calloc(1024, 1);
    size_t size = 1024;
    getline(&line, &size, stdin);
    free(line);
}

突然之间没事!

以上是关于Valgrind报告从stdin的getline后释放的指针上的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

Valgrind 报告内存肯定丢失而没有错误

MIPS 上的 Valgrind 报告没有堆使用

Valgrind 内存泄漏报告中的时间戳不正确

为啥 valgrind 将我的记忆报告为“肯定丢失”?

valgrind 使用 std::string 报告无效读取

Valgrind 报告嵌套 shared_ptrs 的 =operator 读取错误