Reputation: 1810
I have found a problem when using some existing FORTRAN code. Although it had anticipated the need to deallocate arrays before re-allocating, this had never been necessary. I now need it to do this, and it doesn't function correctly.
The current pseudo-code is approximately:
MODULE mA
TYPE A
REAL, DIMENSION(:,:,:), ALLOCATABLE :: array
END TYPE
TYPE (A), POINTER :: sw(:)
END MODULE
Later, there is the code which allocates the size of 'array', which I'm now calling twice (hitherto only once):
...
IF (ALLOCATED(sw(1)%array)) DEALLOCATE(sw(1)%array, STAT=aviFail)
IF (aviFail.EQ.0) ALLOCATE(sw(1)%array(1,2,3), STAT=aviFail)
...
I've looked at the definition of ALLOCATE, DEALLOCATE and ALLOCATED, and I have found the following:
I had also inadvertently called ALLOCATE on the same array twice elsewhere, without DEALLOCATING first. According to the book, this should result in program termination. It not only works, but works correctly and the STAT return from the second ALLOCATE is '0'.
Does Intel FORTRAN handle these things differently, or is FORTRAN not as fussy about fulfilling its specification as C++?
Upvotes: 2
Views: 2716
Reputation: 131
Without seeing more of the implementation, it is difficult to give a detailed & targeted explanation, but I think it's likely to be the implementation of the pointer that is causing your problem. The "book" answers you gave on the behavior of ALLOCATE and DEALLOCATE sound correct, but you described how they behave when working directly with an allocatable array. ALLOCATE and DEALLOCATE may function differently (compiler dependent) when operating on a pointer. At the most basic level, allocating memory through a pointer requires more steps: 1) determine the type/dimension of object to be created for the pointer, 2) create and allocate an unnamed object of that type/dimension in memory, 3) associate the pointer with the new object. Depending on the implementation, compiler, and other factors these extra steps can add complexity to the observed behavior of a program.
Is there a particular reason for using a pointer in this implementation? If not, I would recommend switching to a simpler normal allocatable array to see if the problem persists.
Regarding you being able to ALLOCATE and array twice by mistake without the expected program termination: I think this is also related to your implementation using a pointer. The pointer you are re-allocating is already associated with a location in memory. It is likely that this association changes the manner in which the compiler handles the ALLOCATE statement as it is executed the second time. If the pointer is already associated with a memory position with the dimensions the ALLOCATE statement is asking for, then there is no reason to terminate the program or throw an error; the programmer is getting exactly what he or she asked for.
In closing, the ALLOCATE/DEALLOCATE statements and pointer association/nullification are handled differently by different compilers, so it's not surprising that your observing behavior not in accordance with "the book." I would recommend taking a look at whether you really need the pointer implementation and be sure to be applying memory management best practices as you code.
Upvotes: 3