0

I'm learning Fortran with the book Fortran 90 for scientists and engineers by Brian Hahn. In chapter 9 about arrays, pages 131/132, he gives the following code as an example of dynamic arrays

Program Chap_9_Allocatable_Array

Implicit none

! Variables
Real, dimension(:), Allocatable    :: X, OldX
Real                                  A
Integer                               IO, N, i

! Body of Chap_9_Allocatable_Array
Allocate( X(0) )                   !Size zero to sart with?
N = 0
Open(1, File = 'Data.txt')

Do
    Read(1, *, IOStat = IO) A
    If (IO < 0) Exit
    N = N + 1
    Allocate( OldX( Size(X) ) )
    OldX = X                       !Entire array can be assigned
    Deallocate( X )
    Allocate( X(N) )
    X = OldX
    X(N) = A
    Deallocate( OldX )
End do

Print *, (X(i), i = 1, N)

End program Chap_9_Allocatable_Array

I have implemented this program in Visual Studio Community 2019 with the Intel Visual Fortran Compiler. The purpose of this program as he explains is

The following program extract shows how to use allocatable arrays, as these beasts are called, to read an unknown amount of data, which unfortunately must be supplied one item per line because of the way READ works.

I found an interesting error. The file data.txt consists of 100 random numbers, 1 per row. When I try to run it, it just seems to stall for a couple of seconds and then the console simply prints the

Press any key to continue.

prompt, without an error message. I have inserted some debug prints and determined that the program runs the do cycle between 3 to 8 times before stopping. I have not been able to determine the reason. If I then change the data.txt file to only be 3 numbers long, the program runs as intended. With the debug prints, I have pinned the error to being the

Deallocate( X )

line. If I debug the program in Visual Studio I just get the following message:

Chap_9_Allocatable_Array.exe has triggered a breakpoint.

There have been a few minor errors in the book. Just in this example, the author seems to have forgotten to declare i, which caused a compile error. However, as I'm only beggining to understand arrays, I don't know what else to try. Any ideas?

  • 1
    X = OldX - is this exactly what it says in the book? If so think carefully why it might not be correct – Ian Bush Nov 08 '20 at 10:45
  • This is a poor approach to reading contents from a file of unknown size. When the loop exits, you have done 2*N+1 `ALLOCATE`s and 2*N `DEALLOCATE`s. There's also N copying of data from 1 array to another. That's bad design. Depending on the compiler options, and considering @IanBush's comment, you may be doing an additional N `ALLOCATE`s and `DEALLOCATE`s and writing to an out-of-bounds array location. It would be better to read the file, simply counting the number of lines in 1 do-loop. Then rewind the IO unit, allocate `X(N)` once, and then re-read the file in a 2nd do-loop. – evets Nov 08 '20 at 19:05
  • 1
    as far as i understand the question he is not trying to optimize the book's code but rather to debug it. for that @IanBush's comment should be perfect – jack Nov 08 '20 at 19:29
  • @jack, Actually, Ian's comment is not perfect. `X = OldX` is valid modern Fortran, where re-allocation on assignment occurs. The problematic statement is the next one: `X(N) = A` steps off the re-allocated `X`. Either he should completely rewrite the code to avoid the unnecessary allocations and deallocations or change the assignment to either `X(1:n-1) = OldX` or `X = [Oldx, A]`. – evets Nov 08 '20 at 22:35
  • I agree that this is a poor approach to reading contents. The author himself acknowledges this and gives better code for this task before and after this example, he seems to want a simple example, but it is either outdated or poorly implemented. I was able to fix most mistakes, but this one took me by surprise. As for the solution, the last one worked for me. `X(1:n-1) = OldX` succesfully completed the program, but only the first number was read correctly, and every other one seemed to simply be an overflow mess. The `X = [OldX, A]` one worked flawlessly. Thank you. – Ottmar Schaub Nov 08 '20 at 23:47
  • 1
    @evets - Oh I am happy that the statement in isolation is correct. However it is still wrong in terms of the program logic, reallocation is incorrect here - hence my comment. But the OP seems to have made major steps in sorting it out themselves, which was my main point, as doing it that way they will learn so much more than being told the answer. – Ian Bush Nov 09 '20 at 08:52

0 Answers0