为什么 valgrind 报告我的记忆“绝对丢失"? [英] Why valgrind report my memory as "definitely lost"?
问题描述
考虑这个代码:
#include int* alloc(){返回 malloc(250 * sizeof(int));}int main(){国际我;int *vars[3];for(i = 0; i <3; ++i) {vars[i] = alloc();}}
Valgrind 输出:
$ valgrind --leak-check=full ./lala==16775== Memcheck,内存错误检测器==16775== 版权所有 (C) 2002-2013 和 GNU GPL,由 Julian Seward 等人所有.==16775== 使用 Valgrind-3.10.1 和 LibVEX;使用 -h 重新运行以获取版权信息==16775== 命令:./lala==16775====16775====16775== 堆摘要:==16775== 退出时正在使用:3 个块中的 3,000 字节==16775== 总堆使用量:3 次分配,0 次释放,已分配 3,000 字节==16775====16775== 3 个块中的 3,000 字节在丢失记录 1 of 1 中肯定丢失==16775== 在 0x4C2BBA0:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so 中)==16775== by 0x4005B3: alloc (lala.c:5)==16775== 由 0x4005DF: main (lala.c:13)==16775====16775== 泄漏摘要:==16775== 肯定丢失了:3 个块中的 3,000 个字节==16775== 间接丢失:0 个块中的 0 个字节==16775== 可能丢失:0 个块中的 0 个字节==16775== 仍然可达:0 个块中的 0 个字节==16775== 被抑制:0 个块中的 0 个字节==16775====16775== 对于检测到和抑制的错误的计数,重新运行: -v==16775== 错误摘要:来自 1 个上下文的 1 个错误(被抑制:来自 0 的 0)
根据Valgrind 的手册:><块引用>
如果适当地设置了 --leak-check,对于每个剩余的块,Memcheck 确定块是否可以从根集.根集由 (a) 通用寄存器组成所有线程,以及 (b) 初始化、对齐、指针大小的数据字可访问的客户端内存,包括堆栈.
据我所知,由于仍然从 main()
函数的堆栈中指向绝对丢失"的内存,它们应该归类为仍然可达",对吗?
如果不是,我该如何配置 Valgrind 以尝试从 main
的堆栈中访问内存块,以确定它们是否仍然可以访问"?
请不要告诉我要free
main
末尾的指针,这不是我要问的.有关 Valgrind 术语中仍可到达"和绝对丢失"的区别,请参阅此答案:https://stackoverflow.com/a/3857638/578749
当main
的栈被销毁,也就是返回的时候,你的记忆肯定会丢失.因此,解决方案是不返回.
#include int main(){/* 你的代码在这里 */退出(0);}
行为或主要返回 0 或 exit(0)
应该是等效的.
现在输出是:
==5035== Memcheck,一个内存错误检测器==5035== 版权所有 (C) 2002-2013 和 GNU GPL,由 Julian Seward 等人所有.==5035== 使用 Valgrind-3.10.1 和 LibVEX;使用 -h 重新运行以获取版权信息==5035== 命令:./a.out==5035====5035====5035== 堆摘要:==5035== 退出时使用:3 个块中的 3,000 字节==5035== 总堆使用量:3 次分配,0 次释放,已分配 3,000 字节==5035====5035== 泄漏摘要:==5035== 肯定丢失了:0 个块中的 0 个字节==5035== 间接丢失:0 个块中的 0 个字节==5035== 可能丢失:0 个块中的 0 个字节==5035== 仍然可达:3 个块中的 3,000 字节==5035== 被抑制:0 个块中的 0 个字节==5035== 未显示可到达的块(找到指针的块).==5035== 要查看它们,请重新运行:--leak-check=full --show-leak-kinds=all==5035====5035== 对于检测到和抑制的错误的计数,重新运行: -v==5035== 错误摘要:0 个上下文中的 0 个错误(被抑制:0 个中的 0 个错误)
Consider this code:
#include <stdlib.h>
int* alloc()
{
return malloc(250 * sizeof(int));
}
int main()
{
int i;
int *vars[3];
for(i = 0; i < 3; ++i) {
vars[i] = alloc();
}
}
Valgrind output:
$ valgrind --leak-check=full ./lala
==16775== Memcheck, a memory error detector
==16775== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==16775== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==16775== Command: ./lala
==16775==
==16775==
==16775== HEAP SUMMARY:
==16775== in use at exit: 3,000 bytes in 3 blocks
==16775== total heap usage: 3 allocs, 0 frees, 3,000 bytes allocated
==16775==
==16775== 3,000 bytes in 3 blocks are definitely lost in loss record 1 of 1
==16775== at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16775== by 0x4005B3: alloc (lala.c:5)
==16775== by 0x4005DF: main (lala.c:13)
==16775==
==16775== LEAK SUMMARY:
==16775== definitely lost: 3,000 bytes in 3 blocks
==16775== indirectly lost: 0 bytes in 0 blocks
==16775== possibly lost: 0 bytes in 0 blocks
==16775== still reachable: 0 bytes in 0 blocks
==16775== suppressed: 0 bytes in 0 blocks
==16775==
==16775== For counts of detected and suppressed errors, rerun with: -v
==16775== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
According to Valgrind's manual:
If --leak-check is set appropriately, for each remaining block, Memcheck determines if the block is reachable from pointers within the root-set. The root-set consists of (a) general purpose registers of all threads, and (b) initialized, aligned, pointer-sized data words in accessible client memory, including stacks.
For what I understand, since the "definitely lost" memory are still pointed to from the main()
function's stack, they should be categorized as "still reachable", right?
If not, how can I configure Valgrind to try to reach memory blocks from main
's stack, to determine if they are "still reachable"?
EDIT:
Please don't tell me to free
the pointers at the end of main
, that is not what I am asking about. For the distinction between "still reachable" and "definitely lost" on Valgrind terms, see this answer: https://stackoverflow.com/a/3857638/578749
Your memory is definitely lost when the stack of main
is destroyed, that is, when it returns. Thus, the solution is not to return.
#include <stdlib.h>
int main()
{
/* your code here */
exit(0);
}
The behavior or main returning 0 or exit(0)
should be equivalent.
Now the output is:
==5035== Memcheck, a memory error detector
==5035== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5035== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==5035== Command: ./a.out
==5035==
==5035==
==5035== HEAP SUMMARY:
==5035== in use at exit: 3,000 bytes in 3 blocks
==5035== total heap usage: 3 allocs, 0 frees, 3,000 bytes allocated
==5035==
==5035== LEAK SUMMARY:
==5035== definitely lost: 0 bytes in 0 blocks
==5035== indirectly lost: 0 bytes in 0 blocks
==5035== possibly lost: 0 bytes in 0 blocks
==5035== still reachable: 3,000 bytes in 3 blocks
==5035== suppressed: 0 bytes in 0 blocks
==5035== Reachable blocks (those to which a pointer was found) are not shown.
==5035== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==5035==
==5035== For counts of detected and suppressed errors, rerun with: -v
==5035== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
这篇关于为什么 valgrind 报告我的记忆“绝对丢失"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!