Fortran矩阵分配出现无效内存引用错误的技术求助
问题排查与修复方案
核心错误点
- 非法内存访问:代码先执行
deallocate(final_spot)释放矩阵内存,之后才调用minval(final_spot)读取矩阵值并打印,访问已释放的内存是直接导致运行报错的原因。 - 整数隐式截断风险:
n_spot是整数类型,直接将浮点运算结果n_spot - (n_spot * 0.018)赋值给整数变量,小数部分会被默认截断,逻辑不明确。 - 矩阵维度不匹配:初始分配
final_spot时用的是初始值n_spot=125作为列数,后续日循环中n_spot不断缩小,如果需要矩阵尺寸跟随存活点位数量动态变化,需要在每次循环中重分配矩阵。 - 补充:如果编译阶段提示
truncated_normal未定义,需要确保你已经实现了该截断正态分布生成子程序,或者链接了包含该子程序的源码/库文件。
修复后参考代码
PROGRAM Rice_model IMPLICIT NONE real, allocatable, dimension (:,:) :: final_spot real, dimension(125) :: size_small_spot, size_large_spot integer :: days, i, j, n_spot, initial_spot ! 建议用Fortran2008标准的kind定义,避免real(kind=8)的移植性问题 integer, parameter :: dp = kind(1.d0) real(dp) :: mu_small_spot,lower_small_spot,upper_small_spot, size_of_spot real(dp) :: mu_large_spot,lower_large_spot,upper_large_spot integer :: seed real(dp) :: sigma_spot real(dp) :: min, max ! defining variables for the truncated normal distribution for sizes mu_small_spot = 42.8_dp lower_small_spot = 33.0_dp upper_small_spot = 49.0_dp mu_large_spot = 63.7_dp lower_large_spot = 54.0_dp upper_large_spot = 78.0_dp sigma_spot = 4.0_dp seed = 123456789 initial_spot = 125 n_spot = initial_spot days = 20 ! SMALL SPOT do i = 1,initial_spot call truncated_normal(mu_small_spot,sigma_spot, & lower_small_spot,upper_small_spot,seed,size_of_spot) WRITE (*,*) i, size_of_spot size_small_spot(i) = real(size_of_spot) end do min = minval(size_small_spot, dim = 1) max = maxval(size_small_spot, dim = 1) WRITE(*,*) "Min Size = ", min WRITE(*,*) "Max Size = ", max ! LARGE SPOT do i = 1,initial_spot call truncated_normal(mu_large_spot,sigma_spot, & lower_large_spot,upper_large_spot,seed,size_of_spot) WRITE (*,*) i, size_of_spot size_large_spot(i) = real(size_of_spot) end do min = minval(size_large_spot, dim = 1) max = maxval(size_large_spot, dim = 1) WRITE(*,*) "Min Size = ", min WRITE(*,*) "Max Size = ", max allocate(final_spot(1:3,initial_spot)) do i = 1,days ! 显式取整,避免隐式截断 n_spot = n_spot - int(n_spot * 0.018_dp) do j = 1, n_spot final_spot(1,j) = real(j) final_spot(2,j) = size_small_spot(j) final_spot(3,j) = size_large_spot(j) end do end do ! 打印逻辑移到内存释放之前,仅读取已赋值的前n_spot列 WRITE(*,*) "The min values are", minval(final_spot(:,1:n_spot), dim = 2) WRITE(*,*) "The max values are", maxval(final_spot(:,1:n_spot), dim = 2) ! 内存释放放在所有使用矩阵的逻辑最后 deallocate(final_spot) END PROGRAM Rice_model
内容的提问来源于stack exchange,提问作者Kelsey Spencer
相关产品推荐
相关产品推荐

