我有一个子程序,在程序运行过程中经常调用它。我试着使用尽可能多的可分配数组,子程序被调用了好几次都没有任何问题,但在某个时刻,它以结束
malloc.c:3790: _int_malloc: Assertion `(unsigned long)(size) >= (unsigned long)(nb)' failed.
当第一个数组被分配时,这种情况发生在子程序的开头。
使用不可分配数组,子程序被调用的频率会增加几次,但会再次终止,现在是:
wait: 28674: Memory fault(coredump)
我假设它在调用时终止,因为我在变量声明之后立即写出一些值,而不需要任何计算
呼叫
do k=1, kreise
write(*,*)k
call rundheit(n(k),kreis(k,1:n(k),3),kreis(k,1:n(k),2),outrnd)
end do
其中"kreise"的值可能高达1500。我打印并检查了在调用之前、子例程中和调用之后传递的参数值。
限制"kreise"确实解决了问题,但限制并不是一个切实可行的解决方案。我需要评估所有的数据。不是断裂。
我的环境注意事项:
我的程序是一个由FEM仿真软件使用"英特尔Fortran编译器"编译的子程序。据我所知,我没有机会更改编译器选项,也无法单独编译代码,因为它对FEM软件部署的子例程有很多依赖性。
我在另一个更小、更简单的仿真上开发并运行了这个精确的子程序,没有任何问题。只要我不使用这个特定的子例程,实际的"更大"模拟运行也没有任何问题。(差异主要是节点密度,因此计算过程中考虑的数据量)其他用户子程序工作没有问题。子程序所做的就是在不改变模拟的情况下,获取一些增量之间的结果,进行一些分析并编写一些报告。
我想这个问题与记忆处理有关,我对此一无所知。
谢谢。
更新
我使用-check all
编译了子例程,发现错误发生在被指责的子例程之前。两个数组,其中一个是n(),在某些情况下会越界,但在调用时,错误会变得更加严重。奇怪的是,当错误发生时,有些迭代超出了界限,例如:这里两个数组的大小都是(1:72)
,调用在某个地方中断,k=135到267(我在一些运行中发现的最低和最高值)。
问题是整数Kreise
,该值在循环期间设置:
...
allocate(n(l))
allocate(pos(l))
...
do kreise = 1,l
pos(kreise)=minvalX+(Kreise-1)*IncX
if(pos(kreise).gt.maxvalX) exit
end do
其中kreise
始终变为l+1。为什么?
注意:pos(kreise).gt.maxvalX
不应为true。尽管这表明l
的计算是错误的(非常大),但判断为真并不是问题。这种退出只会通过减少几个循环的迭代来节省以后的计算时间。
程序可能正在写入不应该写入的内存,并破坏Fortran分配使用的malloc的内存管理结构。我建议使用Fortran选项进行运行时下标检查。使用ifort,请尝试-check all
或-check bounds
。