使用 malloc 时,如果它产生带有错误的核心转储:
malloc(): memory corruption: ....... ***
这是否意味着 malloc 试图分配不能自由分配的内存?如果那是什么原因造成的?
这完全取决于您的 malloc 实现,但通常这意味着在该 malloc 之前的某个时间点,某些东西向 malloced 缓冲区写入了比其大小更多的数据。
许多 malloc 实现将一些数据存储在内存中,换句话说:
+--------------------------------+
|14 bytes -> Padding |
+--------------------------------+
|2 bytes -> Internal malloc info |
+--------------------------------+
|6 bytes -> Your data |
+--------------------------------+
|8 bytes -> Padding |
+--------------------------------+
|2 bytes -> Internal malloc info |
+--------------------------------+
因此,如果您的某些代码或库向该 6 字节缓冲区写入 16 字节,它将覆盖填充和内部 malloc 信息的 2 字节。下次您调用 malloc 时,它会尝试遍历其数据以查找空间,命中被覆盖的空间,这将是荒谬的,因为您覆盖了它,破坏了堆。
根据实现的不同,这样的错误也可能是由双重释放引起的。
很可能,这不是 malloc 本身的问题。相反,这是您的应用程序修改不应该修改的部分堆的问题。
如果您在 Linux 上运行,请尝试使用Valgrind查看哪些代码正在破坏您的堆。
造成这种情况的通常原因是您写入了 malloc() 未授予您写入权限的数据 - 缓冲区溢出(写入超出给定空间的末尾)或缓冲区不足(写入缓冲区开始之前) )。
有时可能是由于释放了一个未由 malloc() 等分配的指针,或通过重新释放(双重释放)由 malloc() 分配的指针。例如,释放静态缓冲区是一个坏主意;你会腐败。
您应该假设问题出在您的代码中 - 在 malloc() 等中极不可能出现问题,而且不太可能出现在您正在使用的任何其他库中。
有几件事是堆损坏的常见原因:
这些问题可能很难调试,因为原因和结果通常被时间和空间(不同的代码区域)分开。因此,直到导致问题的错误执行后的永恒(计算机时间)过去后,该错误才会被注意到。
使用调试堆对调试这些问题非常有帮助。Microsoft 的编译器有一个在调试版本中启用的CrtDebug 堆(但可以设置其他配置项)。我不确定 GCC 有什么开箱即用的功能,但有一些我熟悉的工具,例如Valgrind 和 Electric Fence,可能会有所帮助。最后,还有大量可能有用的本土堆调试库(Google 左右)。
您能否提供您的 malloc() 语句?
另外,我想仔细检查返回值是否不为空?
malloc()
除了没有要分配的内存之外,我在使用或new
类似您提到的性质时遇到的问题实际上是由损坏的堆造成的。我通常会在程序的其他地方发现一些“有趣”的代码,比如 memcpy(),它的字符缓冲区会导致缓冲区溢出和地址空间受损。
-bn