使用malloc时,如果它产生带有错误的核心转储:
malloc(): memory corruption: ....... ***
这是否意味着malloc试图分配无法自由分配的内存?如果是这样的原因是什么?
答案 0 :(得分:17)
它完全取决于你的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时,它会尝试遍历它的数据来查找空间,点击被覆盖的空间,因为你覆盖它会破坏堆,这将是荒谬的。
根据实施情况,这样的错误也可能是由于双重免费造成的。
答案 1 :(得分:11)
最有可能的是,这不是malloc本身的问题。相反,这是您的应用程序修改堆不应该的部分的问题。
如果您在Linux上运行,请尝试使用Valgrind查看哪些代码会破坏您的堆。
答案 2 :(得分:5)
通常的原因是你写了数据,malloc()没有给你写权限 - 缓冲区溢出(写入超出你给出的空间的末尾)或缓冲区欠载(在开始之前写入)缓冲区)。
有时可能是由释放malloc()等未分配的指针,或者重新释放(双重释放)由malloc()分配的指针引起的。例如,释放静态缓冲区是一个坏主意;你会受到腐败。
您应该假设问题出现在您的代码中 - 它在malloc()等中极不可能出现问题,而且不太可能出现在您正在使用的任何其他库中。
答案 3 :(得分:2)
有几种情况是堆损坏的常见原因:
这些问题可能难以调试,因为因果关系通常由时间和空间(代码的不同区域)分开。因此,在导致问题执行的错误之后,永久性(计算机时间)过去之前,错误不会被注意到。
使用调试堆在调试这些问题时非常有用。 Microsoft的编译器在调试版本中启用了CrtDebug heap(但可以设置其他配置项)。我不确定GCC是什么开箱即用的,但是有一些我熟悉的工具,例如Valgrind and Electric Fence可能会有所帮助。最后有大量的home-grown heap debug libraries可能会有所帮助(谷歌周围)。
答案 4 :(得分:1)
你能提供你的malloc()声明吗?
另外,我想仔细检查返回值是否为空?
除了没有开始分配的内存之外,我在使用malloc()
或new
时遇到的问题与您提到的实际上是损坏的堆的结果相似。我经常在程序的其他地方找到一些“有趣”的代码,像memcpy()这样的东西,它带有一个字符缓冲区,导致缓冲区溢出和一个错位的地址空间。
-bn