1
votes

I'm having an issue with my Fortran 90 code involving deallocating an array that is declared in a module and then allocated & initialized within a subroutine. Within my program, I declare a bunch of arrays in modules like real*8, dimension(:), allocatable :: test. Then, in an initialization subroutine, I use the module, allocate the variable with allocate(test(8)), and initialize it with test = 0.d0.

After this, I can print*, test and get the appropriate output: 0.E+0 0.E+0 0.E+0 0.E+0 0.E+0 0.E+0 0.E+0 0.E+0. In addition, a call to allocated(test) returns .TRUE.. Nevertheless, something goes wrong. Directly after the call to allocate(), a call to sizeof(test) returns 0 and a call to deallocate(test) throws the following error:

lib-4422 : UNRECOVERABLE library error 
  A DEALLOCATE statement argument points to a portion of the
 original allocation.
  Original size in bytes for the argument is 512
  Current size in bytes for the argument is 0
Segmentation fault

This all occurs within a larger code, throughout which I've used these arrays with no errors. I only noticed the problem when I tried to deallocate the memory at the end of the program while hunting for a memory leak. I've tried to make a simple program that only does what has been described above (i.e., declare in module, allocate & initialize in subroutine, then print the array and deallocate it within the same subroutine). This simple code, however, works properly and runs without error. Thus, I'm very confused at what could be causing this to misbehave within the context of the larger code. Furthermore, if within my larger code I move the declaration line from the module to the subroutine, everything runs properly.

Any advice would be appreciated! Thanks in advance,

~BCL

1
Note sizeof (vendor extension) and size (fortran intrinsic) are different things. Sounds like you have some errant part of your program corrupting memory. Time for the usual debugging techniques (compile with full debugging options, use static and dynamic code correctness tools, begin bisection to isolate the problematic part of code). - IanH
Are you saying, that you do allocate, sizeof, then deallocate, without any intervening code? Then the failure of deallocate is very strange. If there is intervening code, then obviously look in that code. As suggested by IanH, turn on all debugging options, esp. runtime subscript (bounds) checking. Be sure to have your procedures in modules so that the consistency of the arguments are checked. - M. S. B.

1 Answers

0
votes

When dealing with arrays that are not internal to a single subroutine, I always use the pointer attribute when declaring them instead of the attribute. In practice both will work the same. For example:

module Mod1
contains
  subroutine sub1(Array)
    !*** Declaration of Variables
    implicit none
    !*** External Variables - Arguments
    real(kind=8), pointer, intent(inout) :: Array(:)
    !*** Internal Variables
    real(kind=8), allocatable            :: InternalArr(:)
    !*** Memory allocation
    allocate(Array(1:8))
    allocate(InternalArr(9:10))
    !*** End of Subroutine
  end subroutine sub1
end module Mod1

Once you call sub1, your array will keep its dimensions at any place of your code. You can deallocate and allocate it as much as you need.

Before using pointer I suffered some issues like the one you described and someone suggested me to use pointer instead. Since then, I've become very used to declare arrays this way (if they are meant to remain on the same subroutine or module I keep using allocatable) and it has always shown to be a good way to keep arrays under control.

I really hope this helps... It is my very first answer :) EDIT: I corrected a little error on the example code