1

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

BCL12
  • 11
  • 1
  • 3
    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 Jul 04 '13 at 00:02
  • 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. Jul 05 '13 at 15:23

1 Answers1

0

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

MR_Chicho
  • 1
  • 1
  • 1
    My advise is the opposite: use an ``allocatable`` variable unless you must use a ``pointer`` variable because you can't accomplish the task with an ``allocatable``. ``allocatable`` variables are safer because memory leaks are impossible. See http://stackoverflow.com/questions/2300199/allocatable-arrays-or-pointer-arrays and http://stackoverflow.com/questions/4023371/difference-between-pointer-and-allocatable – M. S. B. Jul 05 '13 at 15:18
  • I knew those two discussion, and I do agree with you, 'allocatable' is more efficient since an 'allocatable' array will be contiguous in terms of memory. However, a proper allocation and deallocation of memory will prevent suffering memory leaks. In fact I deallocate 'allocatable' arrays as if they were 'pointer'. I guess this is a matter of personal prefences though. Anyway, I only suggested 'pointer' as a hint, as they are more versatile in fortran90. But I'm sure that a more experienced fortran programmer could give a better solution – MR_Chicho Jul 05 '13 at 15:31