setpwent 显示 valgrind 中的内存泄漏

发布于 2024-11-17 02:20:22 字数 1636 浏览 2 评论 0原文

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

谢谢您帮助我。

I am checking my program against memory leaks and corruptions and
I have a problem using setpwent.
consider the simple program as:

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

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

when I run this piece of code in valgrind, I get this:

> 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

should I worry about it?
how can I remove this problem?

Second question:
Do I need to free the password entry as:

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

thank you for helping me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寄与心 2024-11-24 02:20:22

对于第一个问题。无论如何,我认为您不需要调用 setpwent 。这是对 getpwent 的第一次调用(在进程启动之后或在 endpwent 之后),它会返回到开始处。

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

单个 set 可能比 end/get 对更快,特别是如果我怀疑整个(或相当大一部分)文件可能缓存在内存中(a)


对于第二个问题,不,你不释放它。请参阅此处。它很可能使用静态缓冲区(用于单线程)或线程本地存储(用于多线程)。

在这两种情况下,管理缓冲区的是调用本身,而不是您的代码(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源代码,但我喜欢一个好的谜题:-)

For the first question. I don't think you need to call setpwent anyway. It's the first call to getpwent (after process start or after endpwent) which goes back to the start.

You only need setpwent if you want to rewind after calling getpwent but without calling endpwent.

A single set is probably faster than an end/get pair, especially if, as I suspect, the whole (or a sizable proportion of the) file may be cached in memory (a).


For the second question, no, you don't free it. See here. It will most likely use a static buffer (for single-threading) or thread-local storage (for multi-threading).

In both cases, it's the calls themselves that manage the buffer, not your code (a).


(a) Interestingly, the values of ent passed back are different on each iteration which certainly looks like separate allocations.

However, since the addresses are only 32 bytes apart and the size of a struct pwd is 32 bytes, that leaves no room for intervening malloc housekeeping information.

So, either the housekeeping information is not inline (unlikely) or you're actually working with an array of structures rather than individual allocations.

The following program shows this in action:

#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;
}

It outputs:

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

which is what leads me to the conclusions above. In any case, the instant I uncomment that free line in my code, I get a core dump, giving more support to my theory.

Now I suppose I could have just gone and had a look at the getpwent source code but I love a good puzzle :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文