0

I'm trying to solve problems related to retaining values, when I use de/allocate in the code shown below (fortran), making a copy array, but the problem persists. I've already seen links related with the topic:

Fortran array automatically growing when adding a value

How to get priorly-unknown array as the output of a function in Fortran

It would be easy and it doesn't make sense (for the purpose of this code) if I know array dimension (input from a txt file).

Possibly I make some mistakes (one of them is obvious: minute dimension against expected total dimension). I will be grateful if someone specify them. Despite of this I can't understand how making a copy array can solve the problem, because I need to de/allocate both the temporary and the main variables.

So, is it possible to read a txt without "variable dimension" info using reallocate (de/allocate)?

That's the code (using f90):

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

(I know better ways to achieve the same goal, that's only an exercise to deepen)

I use this data example (from a txt):

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

That's the result:

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

5
  • Please use tag fortran for all Fortran questions. Commented Dec 25, 2020 at 9:44
  • Be sure to always enable all compiler checks. gfortran -g -Wall -fcheck=all. Valgrid or sanitizations -fsanitize=address,undefined are also useful to find out where the uninitialized values come from. Commented Dec 25, 2020 at 10:07
  • In minuto((i-4):i) you aren't assigning to all values of that array. As you can see, just the last five values are as expected. Commented Dec 25, 2020 at 13:02
  • francescalus is correct. you could be using move_alloc on minuto, then allocating it of larger size and recopying the saved values into it (saved by move_alloc). Commented Dec 25, 2020 at 13:12
  • @VladimirF Thank you, I didn't know some of these flags.It will be helpful. Commented Dec 25, 2020 at 16:16

1 Answer 1

1

In the reallocation process you deallocate minuto and don't save its old data.

This is a sample program which could work out for you

program prueba
  implicit none

  integer, allocatable :: minuto(:)
  integer, parameter   :: n = 2
  integer              :: iounit, ierr, temp(n), i

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

  ! init minuto. needed for move_alloc in first call
  allocate (minuto(0))

  i = 1
  do
    read (unit = iounit, fmt = '(i2)', iostat = ierr) temp(i)

    ! exit loop. still save temp(1:i-1)
    if (ierr /= 0) then
      if (i > 1) call save_temp(i-1)
      exit
    end if

    ! save all of temp
    if (i == n) call save_temp(n)

    i = mod(i, n) +1
  end do

  close (iounit)

  print *, minuto

contains
  subroutine save_temp(n_temp)
    !! append temp(1:n_temp) to minuto

    integer, intent(in) :: n_temp

    integer, allocatable :: temp_reloc(:)

    ! save old data from minuto into temp_reloc
    call move_alloc(minuto, temp_reloc)

    allocate (minuto(size(temp_reloc) + n_temp))

    ! init first part of minuto by its old data
    minuto(:size(temp_reloc))   = temp_reloc

    ! append temp's data
    minuto(size(temp_reloc)+1:) = temp(1:n_temp)
  end subroutine
end program

Output

$  gfortran -g3 -Wall -fcheck=all a.f90 && ./a.out
           5          10          15          20          25          30          35          40          45          50          55           0
Sign up to request clarification or add additional context in comments.

1 Comment

I would point out that move_alloc() is Fortran 2003 and not Fortran 90. It does not really matter these days, but @Isaac appearsedto be asking for Fortran 90 in particular. Otherwise all the links he got before (also in the previous question) apply as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.