setpwent显示valgrind中的内存泄漏

时间:2011-06-24 03:34:04

标签: c memory-leaks valgrind

我正在检查我的程序是否存在内存泄漏和损坏 我使用setpwent时遇到问题。 将简单程序视为:

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

main()
{
    struct passwd *ent=NULL;
    setpwent();
        while ((ent = getpwent()) != NULL) { }
    endpwent();
}

当我在valgrind中运行这段代码时,我得到了这个:

> valgrind  --track-origins=yes
> --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes ./a.out . . . 160 (40 direct, 120 indirect) bytes in 1
> blocks are definitely lost in loss
> record 11 of 11
> ==6471==    at 0x4025BD3: malloc (vg_replace_malloc.c:236)
> ==6471==    by 0x411CA9C: nss_parse_service_list
> (nsswitch.c:622)
> ==6471==    by 0x411D216: __nss_database_lookup (nsswitch.c:164)
> ==6471==    by 0x459BEAB: ???
> ==6471==    by 0x459C1EC: ???
> ==6471==    by 0x411D864: __nss_setent (getnssent_r.c:84)
> ==6471==    by 0x40D304F: setpwent (getXXent_r.c:127)
> ==6471==    by 0x8048469: main (in /root/workspace/cdk-examples/MMC-0.64/a.out)
> ==6471== 
> ==6471== LEAK SUMMARY:
> ==6471==    definitely lost: 40 bytes in 1 blocks
> ==6471==    indirectly lost: 120 bytes in 10 blocks
> ==6471==      possibly lost: 0 bytes in 0 blocks
> ==6471==    still reachable: 0 bytes in 0 blocks
> ==6471==         suppressed: 0 bytes in 0 blocks
我应该担心吗? 我该如何解决这个问题?

第二个问题: 我是否需要将密码输入释放为:

main()
{
    struct passwd *ent=NULL;
    setpwent();
        while ((ent = getpwent()) != NULL) {
            free(ent);
        }
        endpwent();
}
谢谢你的帮助。

1 个答案:

答案 0 :(得分:3)

对于第一个问题。我认为无论如何你都不需要打{{1​​}}。这是对setpwent的第一次调用(在流程开始之后或之后getpwent),这可以追溯到开始。

如果您想在调用endpwent后回复但不调用setpwent,则只需getpwent

单个endpwent可能比set对更快,特别是如果我怀疑整个(或相当大比例的)文件可以缓存在内存中(a )


对于第二个问题,不,你不要释放它。见here。它很可能使用静态缓冲区(用于单线程)或线程局部存储(用于多线程)。

在这两种情况下,调用本身就是管理缓冲区,而不是代码(a)


(a)有趣的是,传回的end/get的值在每次迭代时都是不同的,当然看起来就像单独的分配一样。

但是,由于地址相距仅32个字节且ent的大小为32个字节,因此无法干预struct pwd内务管理信息。

因此,管家信息不是内联的(不太可能),或者您实际上使用的是一系列结构而不是单独的分配。

以下程序显示了这一点:

malloc

输出:

#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>

int main (void) {
    struct passwd *ent = NULL;
    printf ("ent struct is %d bytes\n", sizeof(*ent));
    while ((ent = getpwent()) != NULL) {
        printf ("pointer is %p, user is %s\n", ent, ent->pw_name);
        // free (ent);
    }
    endpwent();
    return 0;
}

这使我得出上述结论。在任何情况下,我在代码中取消注释ent struct is 32 bytes pointer is 0x4708d0, user is alan pointer is 0x4708f0, user is bill pointer is 0x470910, user is carl pointer is 0x470930, user is dawn pointer is 0x470950, user is ella pointer is 0x470970, user is fran 行的那一刻,我得到一个核心转储,为我的理论提供更多支持。

现在我想我可以刚刚离开并查看free源代码,但我喜欢一个很好的谜题: - )