- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Community,
I am getting a very weird result when I try to access a non existent range in a allocated array.
I define my array as:
integer, parameter :: dp = 8
real(kind=dp), dimension, allocatable(:,:) :: u_out, u_old
Integer :: Imax = 5, Jmax = 11
allocate (u_out(Imax-1,Jmax),u_old(Imax,Jmax))
Notice that the array "x" has a 1 extra row compared to the "x_out". The idea is to copy the contiguous element from the array "x" to "x_out". The last row in the array "x" represents the ghost cells (MPI).
After some computations, I copy the contiguous elements in the following manner:
u_out(:,:) = u_old(1:imax-1,:)
However, when I am writing the values from each array to a file, to double check that the ghost cells are skipped in the array "u_out" I am surprised that the "segmentation fault" error does not come up. Look the following do loop:
do j = 1, jmax
do i = 1 , imax
write(131,*) u_old (i,j), "|", u_out(i,j)
enddo
enddo
Remember that Imax = 5 and Jmax=11. More importantly, the allocated arrays size are different. Neverthless, the writes proceeds with no problem .. Why is this ? How can I access a value that does exists in "u_out". e.g: u_old(5,11).
I also tried to write values such as:
u_out(10,1) and it returns a value.... How is this possible if that size is larger than the one I did allocate?
It is important to mention that the "allocate" takes place in one subroutine and the copy and write to the file takes place in another subroutine. Does the "out of scope" a apply here ?
Thanks
Julio
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Fortran permits indexing beyond array bounds (may pagefault when address not available)
You can enable Runtime Checks for array bounds exceeded (at the expense of slower run times).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"Fortran permits indexing beyond array bounds (may pagefault when address not available)"
No, Fortran, the language, doesn't permit this. If you do it, the results are unpredictable.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"Fortran permits indexing beyond array bounds (may pagefault when address not available)"
No, Fortran, the language, doesn't permit this. If you do it, the results are unpredictable.
Bad choice of words on my part, while Fortran does not authorize access beyond array bounds, it is rather permissive, it that it will not inhibit this type of behavior (excepting when runtime checks are enabled, and/or at compile time when the compiler can determine bounds error).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much for your input. I do appreciate the time you all have spent providing me with your point of view.
Today, I spent more than half an hour because one of the allocatable arrays was indexed with a larger value. The loop was nested with a bunch of counters that was difficult to spot. So, working with dynamic arrays is dangerous, unless I can put some checks. Could you please provide me with the flags that I should use to avoid this issue?
As Dr.Fortran pointed out, the outcome is quite unpredictable.
@John_Campbell I'll try your suggestion, I think that the outcome is as you mentioned, the address will be the same. Although this does not solve the problem, indeed it makes it harder to spot.
@andrew_4619 Sorry, but my knowledge in computer science is very limited and I do not understand the term "explicit interfaces". This case has all variables declared in a simple program, I am not using modules nor subroutine in this "proof of concept" program. This will be implemented in a larger program where all variables are sitting in a module and each subroutine sees the module.
Julio
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That is a good check for mismatched parameters on calls.......
Those two will throw runtime errors on array size problems and are useful for debug builds to find error. For release build these checks can have a speed penalty.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It depends how you declare the subroutines variables, if they are deferred shape and you have explicit interfaces (e.g . the subroutines are in modules) then the compiler will know the array bounds by default and would throw an error. Make a simple complete code that shows the 'error' and post it and you will get some specific advice.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why don't you try the following and review the address of each element of u_old and u_out
write (131,*) 'Address of array elements'
do j = 1, jmax
do i = 1 , imax
write(131,*) i,j," |u_old",loc(u_old (i,j)), " |u_out", loc(u_out(i,j))
enddo
enddo
Hopefully you will find u_out(5,1) and u_out(1,2) have the same location.
Only u_out(5,11) is outside the allocated range of array u_out .
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page