C++ 在OSX上Valgrind报告了这个内存泄漏,它来自哪里?
在OSX上Valgrind报告了这个内存泄漏,它来自哪里?代码是用g++作为C++代码编译的(我是为了函数重载而编写的)。 ==13088==1个块中的18个字节在264的丢失记录82中肯定丢失 ==13088==0x1F25DC:malloc\u区域\u malloc(vg\u替换\u malloc.c:267) ==13088==0xA1AEDA:malloc\u set\u zone\u name(在/usr/lib/system/libsystem\u c.dylib中) ==13088==0xA1B4A7:\u malloc\u初始化(在/usr/lib/system/libsystem\u c.dylib中) ==13088==0xA1B5DD:malloc\u good\u大小(在/usr/lib/system/libsystem\u c.dylib中) ==13088==by 0x4EFA6E:u CFStringChangeSizeMultiple(在/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation中) ==13088==by 0x4F3900:CFStringAppend(在/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation中) ==13088==by 0x506F91:_convertToURLRepresentation(在/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation中) ==13088==0x60F963:\u CFURLInit(在/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation中) ==13088==by 0x4FF268:cfurlCreateWithFileSystemBase(在/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation中) ==13088==by 0x4FF8EE:cfurlCreateWithFileSystemImpression(在/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation中) ==13088==0x515735:CFBundleGetMainBundleAlreadyLocked(在/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation中) ==13088==by 0x515663:CFBundleGetMainBundle(在/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation中) ==13088==by 0x539533:cacheBundleInfo(在/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation中) ==13088==by 0x5394B3:\u CFAppVersionCheckLessThan(在/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation中) ==13088==0x56C35B:u CFInitialize(在/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation中) ==13088==by 0x8FE11243:ImageLoaderMachO::doImageInit(ImageLoader::LinkContext常量&)(in/usr/lib/dyld) ==13088==by 0x8FE10CB3:ImageLoaderMachO::doInitialization(ImageLoader::LinkContext常量&)(in/usr/lib/dyld) ==13088==by 0x8FE0E21F:ImageLoader::recursiveInitialization(ImageLoader::LinkContext常量&,unsigned int,ImageLoader::InitializerMingList&)(in/usr/lib/dyld) ==13088==by 0x8FE0E1B5:ImageLoader::recursiveInitialization(ImageLoader::LinkContext常量&,unsigned int,ImageLoader::InitializerMingList&)(in/usr/lib/dyld) ==13088==by 0x8FE0F1BF:ImageLoader::runInitializers(ImageLoader::LinkContext常量&,ImageLoader::InitializerMingList&)(在/usr/lib/dyld中) ==13088==by 0x8FE03655:dyld::initializeMainExecutable()(在/usr/lib/dyld中) ==13088==0x8FE07EF1:dyld::_main(macho_头常量*,无符号长,int,字符常量**,字符常量**,字符常量**)(in/usr/lib/dyld) ==13088==by 0x8FE012EE:dyldbootstrap::start(macho_头常量*,int,char常量**,long,macho_头常量*)(in/usr/lib/dyld) ==13088==0x8FE01062:_dyld_start(in/usr/lib/dyld) ==13088==0xFFF:???C++ 在OSX上Valgrind报告了这个内存泄漏,它来自哪里?,c++,c,macos,memory-leaks,valgrind,C++,C,Macos,Memory Leaks,Valgrind,在OSX上Valgrind报告了这个内存泄漏,它来自哪里?代码是用g++作为C++代码编译的(我是为了函数重载而编写的)。 ==13088==1个块中的18个字节在264的丢失记录82中肯定丢失 ==13088==0x1F25DC:malloc\u区域\u malloc(vg\u替换\u malloc.c:267) ==13088==0xA1AEDA:malloc\u set\u zone\u name(在/usr/lib/system/libsystem\u c.dylib中) ==13088
编辑:还有,我该如何释放这个内存?它看起来更像是在您正在使用的某个库中,如果是这样,那么请确保您正确使用了库的API,但也要知道,有时库会分配全局资源,例如初始化时,在程序退出之前不会释放这些资源 例如,考虑这种情况:
void init_lib(){
static char *buf=NULL;
if (buf==NULL) {
buf = malloc(18);
}
.....
}
库如何在退出之前释放此缓冲区?它不能,直到程序退出并且操作系统回收了它的内存
看到常见的陷阱了吗
编辑:从技术上讲,在上面的示例中,buf可以按照下面的一条注释的建议释放,但许多库都不这么做,因为buf将在程序期间使用,并且当程序退出时,内存将被回收,因此valgrind将其报告为内存泄漏。分配完全超出您的控制范围;对你来说,免费也是不可能的。应将其添加到已知、检测、记录但被忽略的项目列表中(“抑制”是术语) 当我在MacOS X 10.7.2上的valgrind 3.7.0下运行一个程序时,我得到的摘要如下:
==71989==
==71989== HEAP SUMMARY:
==71989== in use at exit: 6,191 bytes in 33 blocks
==71989== total heap usage: 33 allocs, 0 frees, 6,191 bytes allocated
==71989==
==71989== LEAK SUMMARY:
==71989== definitely lost: 0 bytes in 0 blocks
==71989== indirectly lost: 0 bytes in 0 blocks
==71989== possibly lost: 0 bytes in 0 blocks
==71989== still reachable: 6,191 bytes in 33 blocks
==71989== suppressed: 0 bytes in 0 blocks
==71989== Rerun with --leak-check=full to see details of leaked memory
==71989==
==71989== For counts of detected and suppressed errors, rerun with: -v
==71989== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
这是来自一个没有显式内存分配的程序-printf()
可能会触发一些分配,但这些字节中的大部分是在系统库中分配的。显然,您为回溯设置了一个比正常值更深的值(--num callers=N
)
在手册中查找如何正确添加抑制记录,但是valgrind--help
提供:
--num-callers=<number> show <number> callers in stack traces [12]
--error-limit=no|yes stop showing new errors if too many? [yes]
--error-exitcode=<number> exit code to return if errors found [0=disable]
--show-below-main=no|yes continue stack traces below main() [no]
--suppressions=<filename> suppress errors described in <filename>
--gen-suppressions=no|yes|all print suppressions for errors? [no]
在osx上,您需要使用--dsymutil=yes运行valgrind,以获取有关泄漏位置的更多有用信息,我不确定您正在运行的是哪个版本的osx。但在我运行的版本中,valgrind报告这些错误是不可忽略的 类似问题:也可能相关:@bames53的区别在于,此泄漏属于“绝对丢失”类别,而不是“仍然可以访问”是的-这是“绝对丢失”内存,这是一个很大的区别。但它仍然在你的控制之外;在您的程序正确启动之前,它已被分配(是否丢失?)。我会毫不犹豫地添加它作为抑制。我唯一使用的库是SQLite。我确实调用了它的释放函数,所以我不认为这是问题所在。我在回答中添加了一个示例。您有一个关机/清理调用。许多图书馆都有这种行为。然而,据我所知,SQLite没有。我认为OSX的G+正在链接核心基础库并添加初始化调用:<代码>我该如何调用清理?在您的特定示例中,您无法获得该函数外部指针的引用,但您可以始终拥有一个全局结构,用于跟踪该函数的指针
--num-callers=<number> show <number> callers in stack traces [12]
--error-limit=no|yes stop showing new errors if too many? [yes]
--error-exitcode=<number> exit code to return if errors found [0=disable]
--show-below-main=no|yes continue stack traces below main() [no]
--suppressions=<filename> suppress errors described in <filename>
--gen-suppressions=no|yes|all print suppressions for errors? [no]
Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc