Memory management 使用Fortran 90将txt文件读入可分配数组时出现错误结果

Memory management 使用Fortran 90将txt文件读入可分配数组时出现错误结果,memory-management,io,fortran,fortran90,fallocate,Memory Management,Io,Fortran,Fortran90,Fallocate,当我在下面所示的代码(fortran)中使用de/allocate生成复制数组时,我试图解决与保留值相关的问题,但问题仍然存在。我已经看到了与该主题相关的链接: 如果我知道数组维度(从txt文件输入),这将很容易,而且没有意义(对于本代码而言) 可能我犯了一些错误(其中一个是显而易见的:分维度与预期的总维度)。如果有人具体说明,我将不胜感激。尽管如此,我还是不明白复制数组如何解决这个问题,因为我需要同时取消/分配临时变量和主变量 那么,是否可以使用重新分配(de/allocate)读取没有“

当我在下面所示的代码(fortran)中使用de/allocate生成复制数组时,我试图解决与保留值相关的问题,但问题仍然存在。我已经看到了与该主题相关的链接:

如果我知道数组维度(从txt文件输入),这将很容易,而且没有意义(对于本代码而言)

可能我犯了一些错误(其中一个是显而易见的:分维度与预期的总维度)。如果有人具体说明,我将不胜感激。尽管如此,我还是不明白复制数组如何解决这个问题,因为我需要同时取消/分配临时变量和主变量

那么,是否可以使用重新分配(de/allocate)读取没有“可变维度”信息的txt

这就是代码(使用f90):

(我知道实现同样目标的更好方法,这只是一个需要深化的练习)

我使用这个数据示例(来自txt):

这就是结果:


-2144186072 1-2144186072 1 25 0 35 40 45 50

在重新分配过程中,您取消分配minuto,而不保存其旧数据

这是一个示例程序,可以为您解决

programmprueba
隐式无
整数,可分配::minuto(:)
整数,参数::n=2
整数::iounit,ierr,temp(n),i
打开(newunit=iounit,文件='datos.txt')
读取(iounit,*)
! 一分钟。第一次呼叫中需要移动\u alloc
分配(分钟到(0))
i=1
做
读取(单位=iounit,fmt='(i2'),iostat=ierr)温度(i)
! 退出循环。仍然保存温度(1:i-1)
如果(ierr/=0),则
如果(i>1)调用保存温度(i-1)
出口
如果结束
! 保存所有临时文件
如果(i==n)调用save_temp(n)
i=模(i,n)+1
结束
关闭(iounit)
打印*,分钟
包含
子程序保存温度(n温度)
!! 将temp(1:n_temp)附加到minuto
整数,意图(in)::n_temp
整数,可分配::temp_reloc(:)
! 将minuto中的旧数据保存到temp_reloc中
呼叫移动分配(分钟,临时重新启动)
分配(分钟到(大小(临时重新登录)+n临时))
! 通过其旧数据初始化minuto的第一部分
分钟(:大小(临时重新调整))=临时重新调整
! 附加临时数据
minuto(大小(温度重新调整)+1:)=温度(1:n温度)
结束子程序
结束程序
输出

$gfortran-g3-Wall-fcheck=所有a.f90&./a.out
5          10          15          20          25          30          35          40          45          50          55           0

请对所有Fortran问题使用标记。确保始终启用所有编译器检查
gfortran-g-Wall-fcheck=all
。Valgrid或sanitizations
-fsanitize=address,undefined
也有助于找出未初始化值的来源。在
minuto((i-4):i)
中,您没有将该数组的所有值都赋值。如您所见,只有最后五个值与预期值相同。francescalus是正确的。您可以在
minuto
上使用
move\u alloc
,然后将其分配较大的大小,并将保存的值重新压缩到其中(由move\u alloc保存)。@VladimirF谢谢,我不知道这些标志中的一些。这会很有帮助。我想指出
move\u alloc()
是Fortran 2003,而不是Fortran 90。现在这并不重要,但@Isaac似乎特别要求Fortran 90。否则,他之前得到的所有链接(也在上一个问题中)也适用。
program prueba
    implicit none
    integer, dimension(:), allocatable :: minuto, temp
    integer :: iounit, ierr
    integer :: i = 1
    integer :: n = 1

    open(newunit = iounit, file = 'datos.txt')
    read(iounit,*)

    allocate(minuto(n), temp(n))
    minuto = 0; temp = 0
    !-------------------------------------------

    do
        read(unit = iounit, fmt = '(i2)',iostat = ierr) temp(i)
        if (ierr/=0) exit

            if (mod(size(temp,1),5)==0) then
                deallocate(minuto)
                allocate(minuto(i))
                minuto((i-4):i) = temp((i-4):i)
            end if
        i = i+1
        deallocate(temp)
        allocate(temp(i))
    end do

    close(iounit)

print*,minuto

end program prueba
min
 5
10
15
20
25
30
35
40
45
50
55
 0