C++ 在OSX上Valgrind报告了这个内存泄漏,它来自哪里?

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

在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:???
编辑:还有,我该如何释放这个内存?

它看起来更像是在您正在使用的某个库中,如果是这样,那么请确保您正确使用了库的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