c++ STL列表节点内存分配中的段错误

What causes a segfault in C++ STL list node memory allocation?

本文关键字:段错误 错误 列表 STL 节点 内存 分配 c++      更新时间:2023-10-16

我写了一些c++代码,在我的笔记本电脑上运行得很好(在Microsoft编译器和MinGW下的c++下编译)。我正在把它移植到Unix机器上。

我在Unix机器上使用g++和Intel的ipcp进行编译,在这两种情况下,我的程序在运行一段时间后崩溃(段错误)。我可以运行一小段时间而不会崩溃。

当我调试时,我发现当程序试图复制STL列表时发生崩溃-具体来说,当程序试图分配内存以在列表中创建新节点时发生崩溃。我在调试器(TotalView)中得到的错误是"分配调用失败或返回的地址为空。"

每次运行时,崩溃并不总是发生在代码中的同一位置,但总是在分配调用期间发生,以便在STL列表中创建节点。我不认为我的内存快用完了。我有一些内存泄漏,但非常小。还有什么会导致内存分配错误?为什么它发生在Unix机器上而不是在我的PC上?

更新:我使用MemoryScape来帮助调试。当我使用保护块时,程序可以运行而没有崩溃,这进一步表明存在内存问题。最终解决这个问题的方法是"绘制"分配的内存。原来我是在初始化一个变量,但在将其用作数组索引之前没有将其设置为一个值。因此,数组会溢出,因为它正在使用变量内存位置中的任何垃圾——通常是0或其他小数字,所以没有问题。但是,当我运行程序的时间足够长时,它更有可能保存更大的数字,并在我写数组超出边界时破坏堆。在我试图在数组中写入值的代码行中,使用大数绘制分配的内存会导致段错误,并且我可以看到大绘制的数字被用作数组索引。

这可能是由堆损坏引起的—在代码的其他地方,您覆盖了释放的内存,或者在内存分配的界限之外写入内存(缓冲区溢出,或者在分配的内存开始之前写入)。堆损坏通常会导致不相关位置的崩溃,比如STL代码。由于您是在unix平台上,因此应该尝试在valgrind下运行程序,以尝试识别原始堆损坏。

这听起来像是动态内存分配数据结构的损坏,这通常是由其他不相关的代码引起的。这种类型的bug在没有外部工具的情况下很难发现和重现,因为内存布局的任何变化都可能掩盖它。它可能在Windows版本中侥幸成功。

内存调试器是捕获这种损坏的好工具。valgrind, dmallocefence是检查程序正确性的很好的选择。

 I have a few memory leaks, but they're very small.

嗯,如果你运行它一段时间,那么它最终会占用很多内存。这就是泄密的原因。您应该在崩溃时记录内存使用情况,以查看是否有可用的内存。