什么样的问题可以缺乏解除分配的原因?

时间:2012-07-04 20:10:02

标签: memory-leaks fortran glibc memory-management

我目前遇到的问题是我

*** glibc detected *** ./efit: free(): invalid next size (fast): 0x00000000006127f0 ***

使用glibc错误附带的常用内存映射和回溯信息。但是,我无法找到这个问题的原因。似乎(基本上)我的整个程序在发生这种情况时就完成了。我在网上看到的一件事是,这可能是由于缺乏解除分配。

现在,我一直在运行程序而没有释放我的一些数组(我的印象是释放会导致内存泄漏,但这只会影响程序运行时的性能和效率)。现在,当我启动程序时,我遇到了这个错误。

我之前执行的程序是否可能没有取消分配我的数组是“回来困扰我”,因为我试图写入以前的执行中存在不自由的内存?

如果不是我完全被这个错误搞糊涂了。我应该开始查看的地方和/或我应该如何调试才能找到它的任何线索?

对于它的价值,我正在使用gfortran进行编译

编辑: 虽然编译选项最初没有直接识别这个问题,但它帮助我把它弄清楚了。我在iat循环中使用iat=1,natoms的整数变量do,然后在几行之后,认为iat描述了{{1}范围内的不同整数1}}。我正在引用数组边界之外的数组。当我更正了您的编译选项列出的一些警告时,此错误变为更清晰的错误描述:1,natoms

是什么让这个错误第一次产生?编辑警告告诉我的唯一覆盖变化是Fortran runtime error: Index '7' of dimension 1 of array 'isnormed' above upper bound of 6读取(fout,'(a)')line100'(删除逗号)并将旧样式字符描述read(fout, '(a)'), line100' to更改为更新character*100 line100个描述。

2 个答案:

答案 0 :(得分:1)

此消息与解除分配失败无关。它说堆是腐败的。有很多种方法可以实现,但忘记释放数组并不是其中之一。如果这是Fortran代码,则必须是错误声明的数组。

glibc执行一致性检查时生成消息。所以消息发生时(运行的开始或结束)是不相关的,除非您知道在消息出现之前的某个时间(但可能是任何时间)发生了损坏。

损坏的堆意味着您的程序生成的答案可能是从完全正确到完全无用的任何事情。你必须摆脱这个消息。

  

(我的印象是解除分配会导致内存泄漏,但这只会影响程序运行时的性能和效率

这是落后的。当释放 时,会发生内存泄漏。

最好的方法是使用valgrind之类的工具来详细检测和报告堆问题。

答案 1 :(得分:1)

上一次运行程序的错误无法影响下一次运行。操作系统加载新版本的可执行文件并为其提供内存。只有当程序将信息写入文件并在下次运行时读入时才可以传输信息。

程序完成后,操作系统会自动释放内存。此外,对于Fortran> = 95,过程返回时,Fortran会自动释放过程本地的可分配数组。

很可能您的内存使用问题破坏了描述程序使用的内存的内部结构。使用Fortran,可以通过在调用者和被调用者之间使用参数不匹配,通过索引遍历数组的末尾或指针来实现。你在使用指针吗?如果没有,前两个在这个时代通常很容易防范。将您的程序放入模块并“使用”这些模块。这将允许编译器检查参数一致性。使用下标的运行时检查选项进行编译。这将查明您是否正在索引数组的末尾并存储在其他内存中。

使用gfortran,尝试以下编译器选项:-O2 -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck = all -std = f2008 -pedantic -fbacktrace。如果其中一些识别出太多警告,那么这个问题的重要一点是fcheck = all,甚至更窄,fcheck = bounds。