C++ C++;:使用std::map的微小内存泄漏
我正在编写一个定制的文本文件数据解析器(类似JSON),我花了很多时间试图找到其中的一个小内存泄漏 我正在使用VC++2008和命令_CrtMemCheckpoint和_crtdumpmomeryleaks检查内存泄漏 当我解析任何文件,然后将其从内存中删除(与任何其他已声明的内存一起),我会得到一个16字节的内存泄漏,如下所示:C++ C++;:使用std::map的微小内存泄漏,c++,memory,memory-leaks,C++,Memory,Memory Leaks,我正在编写一个定制的文本文件数据解析器(类似JSON),我花了很多时间试图找到其中的一个小内存泄漏 我正在使用VC++2008和命令_CrtMemCheckpoint和_crtdumpmomeryleaks检查内存泄漏 当我解析任何文件,然后将其从内存中删除(与任何其他已声明的内存一起),我会得到一个16字节的内存泄漏,如下所示: {290} normal block at 0x00486AF0, 16 bytes long. Data: < H `aH hH eH > C0
{290} normal block at 0x00486AF0, 16 bytes long.
Data: < H `aH hH eH > C0 9A 48 00 60 61 48 00 18 68 48 00 D8 65 48 00
classDefinitions是一个std::map
并且是我的解析器类的私有成员
FastStr是一个简单的char*“包装器”,允许简单的c字符串作为键值;它没有内存泄漏(没有“新”命令)。'FSLClassDefinition*'显然是一个简单的类指针,所以这里也没有什么奇怪的
现在有一个问题:
有人能对此发表评论吗?让我们排除一件事:
std::map
中没有漏洞。代码是每个开发人员都可以看到的,到现在它已经被捕获了
如果你是正确的,我可以想象泄漏发生在复制
classDef
或匿名FastStr
对象中。但是如果没有这两个方面的代码,就很难说了。你说它们都是指针,让我相信这句话只是一种症状,而不是真正的问题。显示一些代码怎么样?让我们排除一件事:std::map
中没有泄漏。代码是每个开发人员都可以看到的,到现在它已经被捕获了
如果你是正确的,我可以想象泄漏发生在复制
classDef
或匿名FastStr
对象中。但是如果没有这两个方面的代码,就很难说了。你说它们都是指针,让我相信这句话只是一种症状,而不是真正的问题。显示一些代码怎么样?因为内存“泄漏”不会随着重复使用而扩展,它可能根本不是泄漏,而是由库分配的内存,直到内存分析完成后才会释放。内存通常由库分配,然后在后续调用中重用。因为库无法判断您的调用中的哪一个是最后一个,所以在您的程序退出或稍后退出之前,它不会释放它。因为内存“泄漏”不会随着重复使用而扩展,它可能根本不是泄漏,而是由库分配的内存,直到内存分析完成后才会释放。内存通常由库分配,然后在后续调用中重用。因为库无法判断您的哪个调用是最后一个调用,所以在您的程序退出或稍后退出之前,库不会释放它。我的直觉是查看FastStr。您说它是一个简单的char*包装器,但它如何处理被复制(即内部char*是被复制还是重新创建的)?请给我们看看FastStr的代码好吗
除此之外,您列出的证据表明存在一些静态数据,或者如果您提到的“解析器”只在测试代码块中创建了一个,那么“解析器”对象的一个成员可能是内存泄漏的来源
另一个建议是在更具描述性的工具(如valgrind)下运行代码以查明泄漏?Valgrind(或Purify)将告诉您代码中内存泄漏的精确位置。我的直觉是查看FastStr。您说它是一个简单的char*包装器,但它如何处理被复制(即内部char*是被复制还是重新创建的)?请给我们看看FastStr的代码好吗 除此之外,您列出的证据表明存在一些静态数据,或者如果您提到的“解析器”只在测试代码块中创建了一个,那么“解析器”对象的一个成员可能是内存泄漏的来源
另一个建议是在更具描述性的工具(如valgrind)下运行代码以查明泄漏?Valgrind(或Purify)将告诉您代码中内存泄漏的精确位置。到目前为止,我们还没有看到您的代码中的任何一行,因此我们几乎不可能说得更多,“在所有广泛使用的STL实现中,
std::map
在任何情况下都不会泄漏内存。”一旦映射的析构函数运行,它的所有内存都将被释放
当然,如果您使用的是一些晦涩难懂的专有STL实现,那么一切都是错的,但除此之外,map并不是罪魁祸首
当然,如果您确实怀疑map
内存泄漏,请仔细检查。它是只包含头的代码,所以它是可见的,并且可以像调试自己的代码一样进行调试。在调试器中逐步检查它,查看它进行了哪些分配,以及它们是否再次被释放
但更可能的问题是FastStr或。。。代码中还有其他内容
尝试从代码中剥离尽可能多的内容,以获得再现错误的尽可能小的示例
不要从一开始就运行完整的程序。如果您确定问题出在您发布的行中,那么您可以跳过所有初始解析,这将排除许多可能性。同样,也要删除之后发生的任何事情。如果这没有重现错误,那么问题就不在你所隔离的那条线上
当你得到
classDefinitions[FastStr(cString)] = classDef;
return ((_Ty _FARQ *)::operator new(_Count * sizeof (_Ty)));