背景
我有一个Python脚本,它使用Fortran代码进行密集计算。我正在使用F2Py来做到这一点。一个特定的Fortran子例程构建了一个用于以后计算的矩阵。该子程序在循环中迭代,并在每一步求解。下面给出了使用基本数组和变量的代码片段:
for i in xrange(steps):
x+=dx
F_Output=Matrix_Build_F2Py.hamiltonian_solve(array_1, array_2, array_3, array_4)
#Do things with F_Output
SUBROUTINE Hamiltonian_Solve(array_1, array_2, array_3, array_4, output_array)
!N_Long, N_Short are implied, Work, RWork, LWork, INFO
INTEGER, INTENT(IN), DIMENSION(0:N_Long-1) :: array_1, array_2, array_3
INTEGER, INTENT(IN), DIMENSION(0:N_Short-1) :: array_4
COMPLEX*16,ALLOCATABLE :: Hamiltonian(:,:)
COMPLEX*16, DIMENSION(0:N_Short :: Complex_Var
DOUBLE PRECISION, INTENT(OUT), DIMENSION(0:N_Short-1) :: E
INTEGER :: LWork, INFO, j
COMPLEX*16, ALLOCATABLE :: Work(:)
ALLOCATE(Hamiltonian(0:N_Short-1, 0:N_Short-1))
ALLOCATE(RWork(MAX(1,3*(N_Short-2))))
ALLOCATE(Work(MAX(1,LWork)))
ALLOCATE(E(0:N_Short-1))
DO h=0, N_Long-1
Hamiltonian(array_1(h),array_2(h))=Hamiltonian(array_1(h),array_2(h))-Complex_Var(h)
END DO
CALL ZHEEV('N','U',N_Short,Hamiltonian,N_Short,E,Work,LWork,RWork,INFO)
DO j=0,N_Short-1
Output_Array(j)=E(j)
END DO
END SUBROUTINE
但是,由于某种原因,这个子程序崩溃了我的Python程序,并生成以下malloc错误:
error for object 0x1015f9808: incorrect checksum for freed object - object was probably modified after being freed.
这个错误很不寻常,因为每次都不会发生,但只占很大一部分时间。我已经确定错误的根源在于:
Hamiltonian(array_1(h),array_2(h))=Hamiltonian(array_1(h),array_2(h))-Complex_Var(h)
好像我把它改为:
Hamiltonian(array_1(h),array_2(h))=Hamiltonian(array_1(h),array_2(h))
错误停止。但是,Complex_Var对输出至关重要,否则程序只会产生零。 This线程与我的问题有一些相似之处,但这个问题似乎在每次运行后都会发生,我的不会。我已经注意确保数组没有不匹配,其他安排(即不考虑numpy的不同数组格式)会立即产生分段错误,如预期的那样。
问题
为什么Complex_Var会破坏代码?为什么问题是间歇性的而不是系统性的?是否有任何明显(或不那么明显)的提示可以避免这种情况?
非常感谢任何帮助!
答案 0 :(得分:1)
根据第一条评论和问题修订进行更新:
我发现问题表达式中的某些数组具有高维N_long-1
(即array_1和array_2)和数组Complex_Var维N_short
。循环迭代到N_Long-1
。你知道N_Long-1 <= N_short
吗?如果没有,您可能正在访问非法下标o Complex_var。您是否知道array_1和array_2中的值始终是Hamilton的合法下标?如果在该数组的保留大小之外写入,则可能会损坏内存分配器在创建某个数组时使用的信息,从而阻止它在以后释放该数组。
如果这是问题,使用编译器的运行时下标检查选项可以帮助您找到类似的错误。
答案 1 :(得分:0)
可能是因为您没有deallocate
个命令。然而很难说这个明显不完整的代码 - 你能发布实际的代码(即会编译的东西)吗?