You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fortran程序内存分配异常:malloc(): corrupted top size报错排查

Fortran局部密度程序内存崩溃问题分析与修复

问题成因

报错malloc(): corrupted top size是堆内存被非法写入破坏导致的,核心原因是数组下标越界访问:

  1. 当n_grid=19、ds=3d0、L=59.99999d0时,ds*n_grid=57d0 < L,粒子坐标经过周期性边界条件处理后范围是[0, L)。当坐标接近L(比如59.99999)时,floor(rco/ds)=floor(59.99999/3)=19,加1后得到20,但dn数组的维度是(19,19,19),最大下标为19,此时写入dn(20,q,r)会直接越界,破坏堆内存的管理结构。
  2. 从运行输出能看到sum(dn)=183355远小于n*nc=193536,说明大量粒子的索引越界,未被正确统计到dn数组中,同时非法写入了其他内存区域。
  3. 当n_grid>=20时,ds*20=60d0 >= L,此时floor(L/ds)=19,加1后是20,刚好匹配dn数组的最大下标,不会越界,因此程序正常运行。

修复方案

针对索引越界问题,采用两种互补的修复手段:

  1. 正确计算n_grid:根据盒子尺寸L和网格步长ds,计算刚好能覆盖整个盒子的网格数,避免出现网格范围小于盒子的情况:
    n_grid = ceiling(L / ds)  ! 用天花板函数确保网格总长度>=L
    
  2. 强制索引边界检查:对计算出的网格索引做模运算,确保其始终落在1~n_grid范围内(即使出现浮点精度误差导致的超界):
    p = mod(floor(rco(1, (i-1)*n + j)/ds), n_grid) + 1
    q = mod(floor(rco(2, (i-1)*n + j)/ds), n_grid) + 1
    r = mod(floor(rco(3, (i-1)*n + j)/ds), n_grid) + 1
    
    注:由于坐标已通过周期性边界条件处理为[0,L),floor(rco/ds)结果非负,模运算后范围为0~n_grid-1,加1后刚好是合法的数组下标。

修改后的完整代码

program localdensity

implicit none

    integer :: i , j , k , a , b , n_grid , n , nc , p , q , r , ncin1
    double precision ::  L , ds  , ignore 
    double precision, allocatable :: dn(:,:,:)                               
    double precision, allocatable :: rco(:,:)             
      
    ! INPUT PARAMETERS !

    ncin1 = 14                        ! total configurations in each block file
    nc =  ncin1*1                     ! total block files
    ds = 3d0                          ! dx = dy = dz = 2 A 

    ! INPUT PARAMETERS !

    print*, 'started reading data file'
    open (1, file = 'Silica_13824_negative_press-11_100.txt', status = 'old')  
  
    read(1,*) n ,  ignore  ,  L                          
  
    close(1) 
    
    print* ,  n , L
    L = 59.99999d0
    !L = 60.0001d0

    allocate(rco(3,nc*n))
    ! 修复:正确计算n_grid,确保覆盖整个盒子
    n_grid = ceiling(L / ds)
    print*, 'calculated n_grid: ', n_grid
    allocate(dn(n_grid , n_grid , n_grid))

    open (1, file = 'Silica_13824_negative_press-11_100.txt', status = 'old')  

    do j = 1 , nc

        read(1,*)                            
        do i=1,n
            k=i+(j-1)*n
            read(1,*)  a , b , rco(1,k), rco(2,k), rco(3,k) ! reading data (x,y,z)
        end do
    end do
    print*, 'ended reading data file n :' , n , L
    close(1)  
   
    rco(:,:) = rco(:,:) - L*floor(rco(:,:)/L) ! Appying Periodic Boundary condition

    dn = 0   
    print* 

    do i = 1,nc
        do j = 1,n
            ! 修复:用模运算确保索引在合法范围内
            p = mod(floor(rco(1 , (i-1)*n + j) / ds), n_grid) + 1
            q = mod(floor(rco(2 , (i-1)*n + j) / ds), n_grid) + 1
            r = mod(floor(rco(3 , (i-1)*n + j) / ds), n_grid) + 1
            dn(p,q,r) = dn(p,q,r)  + 1 
         
        end do  
    if (mod(i,ncin1)==0) print*, 'block', i/ncin1, 'done'
    end do

    print*, 'total particles counted :', sum(dn) ,'; n*nc = ', n*nc
    print*, 'nc is ' ,  nc   
    dn = dn/nc
    print*, sum(dn)
    print*,'n_grid' ,n_grid

    open (unit = 2, file = "parameters_neg.txt" , action="write" , status="replace")
        write(2,*) n , nc , L , n_grid
    close(2)

    open (unit = 3, file = "data_from_program_neg.txt" , action="write" , status="replace")
             
    do i = 1 , n_grid
        do j = 1 , n_grid
            do k = 1 , n_grid   
         
                write(3,*) i , j , k , dn(i,j,k)  
         
            end do
        end do                          
    end do  

    close(3)
    
    print*, 'Program has computed everything, data has been saved to data_from_program.txt. Now run file named local_density.py '

endprogram localdensity

内容的提问来源于stack exchange,提问作者Mayank Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:06:03