【问题标题】:setpwent shows memory leak in valgrindsetpwent 显示 valgrind 中的内存泄漏
【发布时间】:2011-06-24 03:34:03
【问题描述】:

我正在检查我的程序是否存在内存泄漏和损坏以及 我在使用 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();
}

谢谢你帮助我。

【问题讨论】:

    标签: c memory-leaks valgrind


    【解决方案1】:

    对于第一个问题。我不认为你需要打电话给setpwent。这是对getpwent 的第一次调用(在进程启动之后或endpwent 之后),它会回到开始。

    如果您想在调用getpwent 但不调用endpwent 之后 倒带,则只需要setpwent。

    单个set 可能比end/get 对更快,尤其是如果我怀疑整个(或相当大比例的)文件可能缓存在内存中(a).


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

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


    (a)有趣的是,ent 传回的值在每次迭代中都不同,这肯定看起来像单独的分配。

    但是,由于地址仅相隔 32 个字节,struct pwd 的大小为 32 个字节,因此没有空间干预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 行时,我得到了一个核心转储,为我的理论提供了更多支持。

    现在我想我可以去看看getpwent源代码,但我喜欢一个很好的谜题:-)

    【讨论】:

      猜你喜欢
      • 2019-07-17
      • 1970-01-01
      • 2019-02-10
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      • 2012-11-07
      • 2020-03-31
      • 2016-03-15
      相关资源
      最近更新 更多