Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

DEALLOCATION of ALLOCATED arrays

Honari__Siavash
Beginner
3,312 Views

I have developed an F90 program containing several allocatable arrays. I used to neglect the DEALLOCATE statement, but recently, I read that it might cause "memory leak" and inefficiency. However, there are still some sources claiming that in Fortran90/95, allocatable variables are automatically deallocated when the variable goes "out of scope".

Since I have used some allocatable arrays in MODULEs with SAVE statements (they are defined in a MODULE and allocated in some subroutine having the USE statement), I'm afraid these arrays never go "out of scope". Besides, due to the complexity of the program, it is hard to make sure which allocated array is not needed anymore.

1) Should I use the DEALLOCATE statement in my F90 code or just adding a RETURN statement at the end of the subroutines will do the trick?

2) Should I avoid using allocatable arrays in MODULEs? (I need to share some arrays between some subroutines, and I thought MODULEs are the way to go)

 

Any help is appreciated.

0 Kudos
1 Solution
jimdempseyatthecove
Honored Contributor III
3,313 Views

1) Explicitly deallocate module allocatables when you no longer desire to maintain the data. The auto-deallocate is dependent upon the placement of the item (descriptor/pointer) being allocated. Also all data declared within module are SAVE regardless of attribute.

2) You should use allocatable arrays in modules when a) the array size is not known until runtime, b) the aggregate sizes of all "static" data will exceed 2GB.

Note for 1). when a procedure is repeatedly called, and the temporary allocations tend to be the same, consider not dealocating the module "temporary" array, but then add code at the beginning of the procedure something like

if(allocated(yourArray)) then
   if(size(yourArray) /= whatYouWant) deallocate(yourArray)
endif
if(.not. allocated(yourArray)) allocate(yourArray(whatYouWant))

 

Note, the above may or may not be necessary depending on how your code interacts with reallocate left hand side. (That feature may do what the above does automatically.)

Jim Dempsey

View solution in original post

0 Kudos
7 Replies
Arjen_Markus
Honored Contributor I
3,312 Views

Since Fortran 95 allocatable arrays (note: this does not hold for variables with the pointer attribute) are automatically deallocated when the variable goes out of scope - for instance a local variable without the SAVE attribute upon returning from a routine.

Variables with the allocatable attribute defined in modules persist until the module goes out of scope - no routine in the stack is using it anymore. That is, according to the standard up to Fortran 2008 or 2018 - in practice most compilers would keep the module alive. That aspect has changed IIRC: now such variables never go out of scope anymore. So practice and standard agree again.

What it boils down to is:

  • If you have allocatables, you cannot have memory leaks
  • If you have pointers, you need to take care of deallocating the memory yourself

Note however, that deallocating memory does not necessarily mean that the memory is (instantly) available for other programs. That is up to the discretion of the operating system.

 

0 Kudos
Honari__Siavash
Beginner
3,313 Views

Thanks Arjen.

First of all, I'm not sure I understand what "pointers" actually are. I think I've never used them.

If I understand correctly, when a SAVE statement is used in a module with an allocatable array, the array would not be automatically deallocated, right? If so, do I need to do it manually?

0 Kudos
jimdempseyatthecove
Honored Contributor III
3,314 Views

1) Explicitly deallocate module allocatables when you no longer desire to maintain the data. The auto-deallocate is dependent upon the placement of the item (descriptor/pointer) being allocated. Also all data declared within module are SAVE regardless of attribute.

2) You should use allocatable arrays in modules when a) the array size is not known until runtime, b) the aggregate sizes of all "static" data will exceed 2GB.

Note for 1). when a procedure is repeatedly called, and the temporary allocations tend to be the same, consider not dealocating the module "temporary" array, but then add code at the beginning of the procedure something like

if(allocated(yourArray)) then
   if(size(yourArray) /= whatYouWant) deallocate(yourArray)
endif
if(.not. allocated(yourArray)) allocate(yourArray(whatYouWant))

 

Note, the above may or may not be necessary depending on how your code interacts with reallocate left hand side. (That feature may do what the above does automatically.)

Jim Dempsey

0 Kudos
Arjen_Markus
Honored Contributor I
3,312 Views

Variables with the SAVE attribute retain their values between routine calls - if they are allocatable, the memory associated with them is also retained.

0 Kudos
jimdempseyatthecove
Honored Contributor III
3,313 Views

Additional information:

If the program is multi-threaded, or if the procedure is recursively called, (or if the procedure is reentrant - not likely) .AND. if the temporary array is to be exclusive to the thread/recursive-level/interrupt-service, then maintain the array descriptor on the stack (IOW not in module).

However, if the array is to be shared, regardless of thread/recursive-level/interrupt-service then place the array descriptor in module .OR. use SAVE attribute.

Jim Dempsey

0 Kudos
Honari__Siavash
Beginner
3,312 Views

Thank you Jim. I appreciate the thorough answer.

You mentioned I could "place the array descriptor in module .OR. use SAVE attribute"; Does it mean I can use SAVE attribute without using MODULE?

I'm sorry but I'm not sure I get what you meant when you mentioned: "how the code interacts with reallocate left hand side" in the first reply.

0 Kudos
jimdempseyatthecove
Honored Contributor III
3,312 Views

If an allocatable is declared in the data section of a procedure .AND. if you want to preserve the values between calls, then use SAVE (there are also available compiler command line options to do this but generally not advised to do so).

USE moduleName is not equivalent to a C #include. Think of it more like a extern...

>>I'm sorry but I'm not sure I get what you meant when you mentioned: "how the code interacts with reallocate left hand side" in the first reply

Open the IVF documentation and in the Search (not index) enter: standard-realloc-lhs

When this behavior is enabled (default for Fortran standards following 2003), then when

array = ExpressionGeneratingAnArrayOrEquateOfDifferentArray

then should array not be allocated then it will automatically be allocated to the shape of the right hand side .OR. or should the array currently be allocated, then the array should be reallocated to the shape of the right hand side. I think it is left as an implementation detail as to if the current shape of the lhs matches the shape of the rhs as to if the lhs is realloicated or reused.

Notes:

1) the rank must be the same (number of dimensions)
2) when realloc-lhs is not in effect, then the shape of lhs must match the shape of the rhs

Jim Dempsey

Jim Dempsey
 

0 Kudos
Reply