setpwent 显示 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();
}
谢谢您帮助我。
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于第一个问题。无论如何,我认为您不需要调用
setpwent
。这是对getpwent
的第一次调用(在进程启动之后或在endpwent
之后),它会返回到开始处。如果您想在调用
getpwent
之后倒回,但不调用endpwent
,则只需要setpwent
。单个
set
可能比end/get
对更快,特别是如果我怀疑整个(或相当大一部分)文件可能缓存在内存中(a)。对于第二个问题,不,你不释放它。请参阅此处。它很可能使用静态缓冲区(用于单线程)或线程本地存储(用于多线程)。
在这两种情况下,管理缓冲区的是调用本身,而不是您的代码(a)。
(a) 有趣的是,每次迭代传回的
ent
值都不同,这肯定看起来像是单独的分配。然而,由于地址仅相距 32 字节,并且 struct pwd 的大小为 32 字节,因此没有空间插入
malloc
内务处理信息。因此,要么内务信息不是内联的(不太可能),要么您实际上正在使用一组结构而不是单独的分配。
以下程序显示了这一点:
它输出:
这就是我得出上述结论的原因。无论如何,当我取消代码中的
free
行注释时,我会得到一个核心转储,为我的理论提供更多支持。现在我想我可以去看看
getpwent
源代码,但我喜欢一个好的谜题:-)For the first question. I don't think you need to call
setpwent
anyway. It's the first call togetpwent
(after process start or afterendpwent
) which goes back to the start.You only need
setpwent
if you want to rewind after callinggetpwent
but without callingendpwent
.A single
set
is probably faster than anend/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 interveningmalloc
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:
It outputs:
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 :-)