Hello,
First, I use Absoft 14.0.2 on Windows 7 64 bits, and I use both the 32 bit and 64 bit compilers, though here I am mainly playing with the 32 bit one.
According to Fortran 95 standard, there is a way to check if allocation succeeded, you just add a "STAT=var" in the ALLOCATE statement (or likewise, in DEALLOCATE statement). The Fortran 2003 standard has also the ERRMSG option, but it does not seem to be recognized by the Absoft compiler.
Now, let's give it a try : the following program reads an integer n, and tries to allocate an n*n integer matrix. So it's expected to fail if n is large enough (with a positive istat). Actually, with the 32 bit compiler, the allocation works for n <= 21700, and fails for greater n. That's a little less than a 1,8 Gb array, and this is rather expected for a 32 bit program. Now, how does it fail for n > 21700 ?
program failure
implicit none
integer :: n, istat, i, j
integer, allocatable :: a(:, :)
read *, n
allocate(a(n, n), stat=istat)
print *, "istat:", istat
if(allocated(a)) then
do i = 1, n
do j = 1, n
a(i, j) = i + j
end do
end do
deallocate(a)
end if
end program
For n between 21701 and 23170, I get a positive istat, as expected : I get a notification that the program couldn't allocate memory.
For n > 23170, I get a zero value in istat. And of course, the program crashes afterwards.
Why does this happen ? It's pretty obvious actually : 23171 is the smallest integer n such that 4*n**2 is greater than 2**31 - 1, the maximum positive integer.
So for such n, the value "wraps around", and the computed amount of memory to be allocated is absolutely not what one would expect : it will be a smaller number - and sometimes negative, but maybe it's not even detected if the memory allocation function has an unsigned parameter. Anyway, in the program, the following loop will overflow the allocated memory (which is shorter than the matrix size), and the program crashes.
Now, I think this is a bug in the memory allocation, and it should be rather easy to patch : for example, in assembler, there is a bit to notify integer overflow (what probably happens here).
This was for the 32 bit compiler, but the same happens with the 64 bit compiler, just with larger values (hence it's less likely to happen in real life) : for example, with n=1,500,000,000 istat is positive, but for n=2,000,000,000, istat=0 and the program crashes again (*).
A quick check with gfortran : it does indeed signal a positive istat in such situation, so it has probably a more "bullet-proof" check here.
Jean-Claude Arbaut
(*) Actually, in 64 bits, the smallest n such that istat is positive in the above program is not very clear to me, as it varies in successive runs of the program (it's around 100,000 I think). Maybe it comes from the Windows OS' management of virtual address space, I'm not sure. But anyway, it's not relevant to the problem shown here.
Just as a side remark, in the post, the source code is unreadable in my navigator, because the background color and the code color are almost the same light grey.