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.SVNgcc 版本 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 内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章