0

背景:
我有一个 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 对输出至关重要,否则程序只会产生零。线程与我的问题有一些相似之处,但是每次运行后似乎都会出现该问题,而我的则没有。我已经注意确保数组没有不匹配,其他安排(即不考虑 numpy 的不同数组格式)会立即产生分段错误,正如预期的那样。

问题
为什么 Complex_Var 会破坏代码?为什么问题是间歇性的而不是系统性的?是否有任何明显(或不那么明显)的提示可以避免这种情况?

任何帮助将非常感激!

4

2 回答 2

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 来说总是合法的下标吗?如果您在该数组的保留大小之外写入,则可能会破坏内存分配器在创建某个数组时使用的信息,从而阻止它稍后释放该数组。

如果这是问题所在,使用编译器的运行时下标检查选项可以帮助您找到类似的错误。

于 2014-01-29T00:26:16.263 回答
0

这可能是因为您没有任何deallocate命令。然而,很难用这个明显不完整的代码来判断 - 你能发布实际的代码(即可以编译的东西)吗?

于 2014-04-07T11:07:57.630 回答