我正在使用unittest-cpp库。我决定用valgrind帮助查看其中一个单元的内存泄漏。我得到了这样的报告:
== 35820 == HEAP SUMMARY:
== 35820 ==在退出时使用:188块中的26,151字节
== 35820 ==总堆使用量:259个分配,71个释放,32,151个字节分配
== == 35820
= 65820 == 148(80个直接,68个间接)1个块中的字节肯定会丢失在65的损失记录43中 == 35820 ==在0x100023D81:malloc(vg_replace_malloc.c:303)
== 35820 == by 0x1002CB8D6:__Balloc_D2A(在/usr/lib/system/libsystem_c.dylib中)
== 35820 == by 0x1002CC21F:__ d2b_D2A(在/usr/lib/system/libsystem_c.dylib中)
== 35820 == by 0x1002C8877:__ dtoa(在/usr/lib/system/libsystem_c.dylib中)
== 35820 == by 0x1002F13E6:__ vfprintf(在/usr/lib/system/libsystem_c.dylib中)
== 35820 == by 0x10031A6C8:__ v2printf(在/usr/lib/system/libsystem_c.dylib中)
== 35820 == by 0x1002F0389:vfprintf_l(在/usr/lib/system/libsystem_c.dylib中)
== 35820 == by 0x1002EE223:printf(在/usr/lib/system/libsystem_c.dylib中)
== 35820 == by 0x10000AA59:UnitTest :: TestReporterStdout :: ReportSummary(int,int,int,float) (TestReporterStdout.cpp:43)
== 35820 == by 0x10000AF9E:UnitTest :: TestRunner :: Finish()const(TestRunner.cpp:43)
== 35820 == by 0x10000B2F4:int UnitTest :: TestRunner :: RunTestsIf(UnitTest :: TestList const&,char const *,UnitTest :: True const&,int)const(in ./BuilderTests)
== 35820 == by 0x10000ACEF:UnitTest :: RunAllTests()(TestRunner.cpp:17) == == 35820
== 35820 ==泄漏摘要:
== 35820 ==绝对丢失:1个区块中的80个字节
== 35820 ==间接丢失:2个区块中的68个字节
== 35820 ==可能丢失:1个块中的2,064个字节
== 35820 ==仍然可以访问:1个块中有4,096个字节
== 35820 ==抑制:183块中的19,843字节
但是valgrind并没有指出我的代码。 然后我决定从GSL库构建和检查单元,它也使用unittest-cpp。我得到了同样的报告。
我可以信任valgrind吗?
答案 0 :(得分:0)
您通常可以信任Valgrind报告事实。但是你如何解释这些很重要。并非所有泄漏都是平等的。
并非所有内存泄漏都存在问题。一个程序可能合法地忽略在关闭期间释放一些对象,如果他们的析构函数已知没有相关的工作要做并因此“泄漏”它们 - 将它留给操作系统以在进程退出时清理内存。
所以,可能是一个真正的问题,当然。但也可能是因为性能或方便原因,图书馆故意泄露某些对象。
如果内存泄漏导致内存使用在运行时持续增加,那么它只是一个问题。
泄漏就像 - 资源被分配一次并持续到程序结束并且永远不会被释放 - 只有真的一个问题,如果该资源的大小很大并且可以被释放早期,所以内存可以用于更好的东西,和/或如果资源有一个析构函数,它是重要的运行。
请记住,一旦程序终止,它分配的所有内存将返回给系统(例如“sysv共享内存”等少数例外情况除外)。在程序终止之后,内存泄漏不会影响系统。
答案 1 :(得分:0)
你通常可以信任Valgrind,因为内存是在那里分配的而不是被释放的。是否是一个问题,是另一个问题。
由于性能原因,这实际上似乎是为stdout / stderr分配的缓冲区,实际上并没有故意被C库释放。
您可以尝试致电:
setbuf(stdout, NULL);
setbuf(stderr, NULL);
作为程序的第一件事,看看Valgrind错误是否会消失。然而,这不是一件好事,因为缓冲区可以提供更好的性能。因此,最好忽略此错误(即将其添加到Valgrind抑制文件中)。
(因为你正在使用单元测试框架,实际上这可能实际上很难做到这一点,因为框架可能会阻碍 - 一种可能是创建静态全局实例将在其构造函数中调用这些对象的对象)