fprintf 内存泄漏

Posted

技术标签:

【中文标题】fprintf 内存泄漏【英文标题】:fprintf memory leak 【发布时间】:2012-02-21 03:00:55 【问题描述】:

我正在使用 XCode 4.2.1 中的 Instruments 来查找一些内存泄漏。 我发现了一个非常奇怪的(至少对我而言)内存泄漏: (函数values_table_get_value 返回一个双精度,output = stdout

这两个问题是: 它是真正的内存泄漏吗? 我该如何清理它? (fprintf 格式 %.3f 对于 double 是错误的?

为了表明泄漏在 fprintf 内部,我将函数的返回值更改为 5.0

并将返回值移至临时变量:

更准确地说,这是一张 asm 代码的图片,显示泄漏是:

我做了一个非常简单的测试:使用sprintf + fprintf 进行打印,但我在 sprintf 发现了泄漏:

我也尝试直接使用printf,但我得到了它的泄漏。

我真的认为问题出在格式上。

最后的尝试,表明没有任何与我的功能相关的东西:

只是为了检查,我用 valgrind 执行:(values_table_print 是函数名) valgrind --leak-check=full --show-reachable=yes ./leastsquares

我的软件版本: valgrind——版本:valgrind-3.7.0 gcc --版本 i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1(基于 Apple Inc. build 5658)(LLVM build 2336.1.00)

【问题讨论】:

抽象一下,这个函数返回一个double,泄漏在fprintf中。 这里重要的问题是:输出的定义是什么? 在这种情况下,输出 = 标准输出。 所以,我的猜测是第一次使用标准输出时会创建一个缓冲区。这会明显泄漏,但没关系,因为它无论如何都会在程序退出时关闭。要验证这一点,您可以尝试将 fprintf 替换为 fputc(32, output);并检查是否发生了相同的虚假内存泄漏 在处理特定格式时,可能是 C 库中的内存泄漏。 【参考方案1】:

不要浪费时间调试

您的设置可能有错误的 gcc 或 valgrind 版本,或者根本不是最新的。

我刚试过:

gcc -o junk /tmp/junk.cpp && ~/src/valgrind/coregrind/valgrind --leak-check=full --show-reachable=yes /tmp/junk

关于下面的sn-p

#include <stdio.h>

int main()

    printf( "%.3f", 3.0 );

配置

OSX 10.7.2 valgrind-3.7.0.SVN

gcc 版本 4.2.1(基于 Apple Inc. build 5658)(LLVM build 2335.15.00)

使用内置规范。 目标:i686-apple-darwin11 配置为:/private/var/tmp/llvmgcc42/llvmgcc42-2335.15~25/src/configure --disable-checking --enable-werror --prefix=/Developer/usr/llvm-gcc-4.2 --mandir=/分享/人 --enable-languages=c,objc,c++,obj-c++ --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$ /-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin11 --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2335.15~25/dst-llvmCore/Developer/ usr/local --program-prefix=i686-apple-darwin11- --host=x86_64-apple-darwin11 --target=i686-apple-darwin11 --with-gxx-include-dir=/usr/include/c++/ 4.2.1 线程模型:posix gcc 版本 4.2.1(基于 Apple Inc. build 5658)(LLVM build 2335.15.00)

Valgrind 输出

==58980== Memcheck, a memory error detector
==58980== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==58980== Using Valgrind-3.7.0.SVN and LibVEX; rerun with -h for copyright info
==58980== Command: /tmp/junk
==58980== 
--58980-- /tmp/junk:
--58980-- dSYM directory is missing; consider using --dsymutil=yes
UNKNOWN task message [id 3229, to mach_task_self(), reply 0x2503]
UNKNOWN task message [id 3229, to mach_task_self(), reply 0x2503]
UNKNOWN task message [id 3414, to mach_task_self(), reply 0x2503]
--58980-- WARNING: unhandled syscall: unix:357
--58980-- You may be able to write your own handler.
--58980-- Read the file README_MISSING_SYSCALL_OR_IOCTL.
--58980-- Nevertheless we consider this a bug.  Please report
--58980-- it at http://valgrind.org/support/bug_reports.html.
3.000==58980== 
==58980== HEAP SUMMARY:
==58980==     in use at exit: 0 bytes in 0 blocks
==58980==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==58980== 
==58980== All heap blocks were freed -- no leaks are possible
==58980== 
==58980== For counts of detected and suppressed errors, rerun with: -v
==58980== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

【讨论】:

感谢您的回答。事实上,我使用的是和你一样的 valgrind、gcc 和 max os x 版本。但我会接受你的回答,因为你做了一个很好的测试。

以上是关于fprintf 内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

MFC内存泄漏调试

如何防止java中的内存泄漏

记录一次DialogFragment 内存泄漏

常见的内存泄漏原因及解决方法

Android ValueAnimator --内存泄漏

Android内存泄漏查找和解决