Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

when is DEALLOCATE necessary?

43 views
Skip to first unread message

Nasser M. Abbasi

unread,
Jan 5, 2013, 4:45:42 AM1/5/13
to
I was wondering if one can give a link or simple answer to this:

In new Fortran (F90/95/etc...), one can allocate memory.

Is one required to deallocate it?

I remember reading that Fortran guarantees no memory
leaks. But I see sometimes code that explicitly calls
Deallocate().

I know I need to read more about this.

Here is an example I was looking at

http://rosettacode.org/wiki/Create_a_two-dimensional_array_at_runtime#Fortran

-------------------------------------------------------
PROGRAM Example

IMPLICIT NONE
INTEGER :: rows, columns, errcheck
INTEGER, ALLOCATABLE :: array(:,:)

WRITE(*,*) "Enter number of rows"
READ(*,*) rows
WRITE(*,*) "Enter number of columns"
READ(*,*) columns

ALLOCATE (array(rows,columns), STAT=errcheck) ! STAT is optional
array(1,1) = 42

WRITE(*,*) array(1,1)

DEALLOCATE (array, STAT=errcheck)

END PROGRAM Example
-------------------------------------

Clearly since DEALLOCATE() is part of the language, then
it is there to be used. right?

What are the rules of thumb to follow on the subject of
memory allocation/deallocation?

If you have a good link to read on this subject, that will be great.

thanks,
--Nasser

Paul Anton Letnes

unread,
Jan 5, 2013, 5:24:11 AM1/5/13
to
If you need that memory back, then you should deallocate. For instance,
global variables never go out of scope, so they won't automatically
deallocate. Also, if you have several local arrays that use a
significant portion of your memory, you may not be able to keep them all
allocated at the same time.

Good luck,
Paul



Tobias Burnus

unread,
Jan 5, 2013, 6:07:29 AM1/5/13
to
Nasser M. Abbasi wrote:
> I was wondering if one can give a link or simple answer to this:
> In new Fortran (F90/95/etc...), one can allocate memory.
> Is one required to deallocate it?

If you are using pointers, you have to call deallocate to free them,
they won't get deallocated automatically. (Well, the operating system
frees them after the program has stopped.)

For allocatables: They are automatically freed at the end of the
subroutine/function in which they are declared. However, if you do not
need them any more, deallocating them before the end of the procedure
makes sense. Also, if you want to re-allocate them (without using
move_alloc), you have to deallocate the variable before you can allocate
it again.

In addition, all allocatable variables with the SAVE attribute are not
automatically deallocated. Thus, if you use, e.g., an allocatable module
variable, it makes sense to deallocate it if you do not need the memory
anymore. Also module variables, variables in the main program and other
variables with the SAVE attribute are not finalized. Thus, if you want
to invoke a user-defined finalizer for them, you have to explicitly
deallocate the variable.


In summary: If you only have allocatables and either no big arrays or if
you need the big arrays until the end of the program, you do not need to
call deallocate. If you run into memory issues and have big arrays,
deallocating them explicitly can reduce the required memory.


> I know I need to read more about this.
> Here is an example I was looking at
> http://rosettacode.org/wiki/Create_a_two-dimensional_array_at_runtime#Fortran
>
> -------------------------------------------------------
> PROGRAM Example
>
> IMPLICIT NONE
> INTEGER :: rows, columns, errcheck
> INTEGER, ALLOCATABLE :: array(:,:)
>
> WRITE(*,*) "Enter number of rows"
> READ(*,*) rows
> WRITE(*,*) "Enter number of columns"
> READ(*,*) columns
>
> ALLOCATE (array(rows,columns), STAT=errcheck) ! STAT is optional
> array(1,1) = 42
>
> WRITE(*,*) array(1,1)
>
> DEALLOCATE (array, STAT=errcheck)
>
> END PROGRAM Example
> -------------------------------------

In this example, the deallocate does not really matter.

At least using Fortran 2008, "array" has implicitly the SAVE attribute
as "array" is declared in the main program. Hence, it will *not* be
finalized automatically (whether it will be automatically deallocated,
depends on the compiler).

But as the deallocate is just before the the program ends, wasting the
memory does not harm as the operating system will take care of freeing
all memory of the program.

However, in order to prevent "valgrind" leak messages or similar
diagnostic, you have to explicitly deallocate allocatable variables
declared in the main program, in the declaration part of modules or
other SAVEd variables.


> What are the rules of thumb to follow on the subject of
> memory allocation/deallocation?

POINTER: It's your responsibility to deallocate them.

ALLOCATABLE: If you leave the scope of the variable (i.e. when you
cannot access them anymore via their name), they are automatically
deallocated. Exception: The have the save attribute (i.e. explicit SAVE,
module variables, variables in the main program).

Tobias

Ian Harvey

unread,
Jan 5, 2013, 7:26:45 AM1/5/13
to
On 2013-01-05 10:07 PM, Tobias Burnus wrote:
> Nasser M. Abbasi wrote:
>> I was wondering if one can give a link or simple answer to this:
>> In new Fortran (F90/95/etc...), one can allocate memory.
>> Is one required to deallocate it?
...
> For allocatables: They are automatically freed at the end of the
> subroutine/function in which they are declared. However, if you do not
> need them any more, deallocating them before the end of the procedure
> makes sense. Also, if you want to re-allocate them (without using
> move_alloc), you have to deallocate the variable before you can allocate
> it again.

A reminder to the OP that F90 is different to the later standards -
DEALLOCATE being very much required under that standard because the
automatic deallocation of unsaved local variables at end of scope didn't
happen. But now the OP can forget that, seeing as there are latter
standards and compilers have moved on.

A quibble - you have to deallocate the variable before you can use it
*as the thing to be allocated in an ALLOCATE statement*. In addition to
MOVE_ALLOC, INTENT(OUT) allocatable dummy arguments and assignment (are
there others?) also allow allocatables to be reallocated without
requiring DEALLOCATE first, and they are pretty common in F2003 code.

...

Nasser M. Abbasi

unread,
Jan 5, 2013, 7:31:25 AM1/5/13
to
On 1/5/2013 5:07 AM, Tobias Burnus wrote:

Hello Tobias;

>Also, if you want to re-allocate them (without using
> move_alloc), you have to deallocate the variable before you can allocate
> it again.
>

Do you consider the following as "re-allocating", where
a variable was once assigned some array, then reassigned
a larger array?

-------------------
program f
implicit none
REAL(4), ALLOCATABLE :: A(:)
A=[1,2,3,4];
A=[1,2,3,4,5,6,7,8] !-- Is this considered re-allocation of A ?
end program f
--------------------

I assume it is not, since it compiles and runs fine.
(had print statments there before, all was ok).

--Nasser


Nasser M. Abbasi

unread,
Jan 5, 2013, 7:38:06 AM1/5/13
to
On 1/5/2013 6:26 AM, Ian Harvey wrote:

> allocatable dummy arguments and assignment (are
> there others?) also allow allocatables to be reallocated without
> requiring DEALLOCATE first, and they are pretty common in F2003 code.
>

I just saw your reply. I assume the above applies to
the following then, which I just asked about, and you seem
to have just answered it?

-------------------
program f
implicit none
REAL(4), ALLOCATABLE :: A(:)
A=[1,2,3,4];
A=[1,2,3,4,5,6,7,8] !-- Is this considered re-allocation of A ?
end program f
--------------------

compiled OK with gfortran -std=f2008 did not need to deallocate(A)
first.

--Nasser

Tobias Burnus

unread,
Jan 5, 2013, 8:18:59 AM1/5/13
to
Nasser M. Abbasi wrote:
>> Also, if you want to re-allocate them (without using
>> move_alloc), you have to deallocate the variable before you can allocate
>> it again.

> Do you consider the following as "re-allocating", where
> a variable was once assigned some array, then reassigned
> a larger array?

I should have used "re-allocation via explicit allocation", i.e.
allocate(a(5))
fails if "a" is allocated.


> A=[1,2,3,4];
> A=[1,2,3,4,5,6,7,8] !-- Is this considered re-allocation of A ?

That's fine (since Fortran 2003) and indeed handles the reallocation
automatically.

But there are cases where it doesn't work, e.g.

read (id, *) n
allocate (array(n))
read (id, *) array

where one has to explicitly allocate an array.



Ian Harvey wrote:
> A reminder to the OP that F90 is different to the later standards - DEALLOCATE being very much required under that standard because the automatic deallocation of unsaved local variables at end of scope didn't happen. But now the OP can forget that, seeing as there are latter standards and compilers have moved on.

Is that actually true? My impressions was that the Fortran standard was
a bit unclear and many compilers didn't deallocate automatically. But
the standard could be interpreted such that the deallocation happens
automatically.

(I started with Fortran 95 at a time when Fortran 2003 was half-ready.
Thus, I might misremember the fine prints of Fortran 90/95.)

Tobias

Richard Maine

unread,
Jan 5, 2013, 12:29:38 PM1/5/13
to
Tobias Burnus <bur...@net-b.de> wrote:

> Ian Harvey wrote:
> > A reminder to the OP that F90 is different to the later standards -
> >DEALLOCATE being very much required under that standard because the
> >automatic deallocation of unsaved local variables at end of scope didn't
> >happen. But now the OP can forget that, seeing as there are latter
> >standards and compilers have moved on.
>
> Is that actually true? My impressions was that the Fortran standard was
> a bit unclear and many compilers didn't deallocate automatically. But
> the standard could be interpreted such that the deallocation happens
> automatically.

Nope. F90 was not vague on the subject. I'd say it was quite clear about
specifying things that were horribly broken in terms of useability for
allocatables. Fortunately, that was fixed in f95 and you won't really
find f90 compilers today; any compiler with any pretext of being
supported got updated to f95 long ago, there not being that huge a step
from f90 to f95. I sometimes say that f95 might almost have been called
f90 release 2.

F90 had 3 possibilities for allocation status: allocated, unallocated,
or undefined. If you ever let an allocatable variable get into the
undefined state, then that variable could never again be used in any
useful way by a standard conforming program.

Of course, you couldn't reference it. You also couldn't deallocate it
necause it wasn't allocated. And you couldn't allocate it because it
wasn't deallocated. You couldn't inquire about its allocation status.
F90 allocatables were worse than pointers in this regard. If a pointer
got undefined association status, you could always just nullify it or
allocate it anyway; you might leak memory as a result, but you could at
least plow on and still have legal code. Allocatables had no way to
"reset and start anew". Once an allocatable got undefined status, it was
never again useable. As of f95, there is no undefined allocation status.

The only thing I can think you might be thinking about is the
implementation side. Even there, I'd say it wasn't unclear. It was clear
that the compiler could do any of multiple things when an allocatable
got undefined association status. It could deallocate it or not, as the
compiler choose, because a standard-conforming program could not tell
the difference.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

Richard Maine

unread,
Jan 5, 2013, 1:11:33 PM1/5/13
to
Nasser M. Abbasi <n...@12000.org> wrote:

> I remember reading that Fortran guarantees no memory
> leaks. But I see sometimes code that explicitly calls
> Deallocate().

No. No. No. Others have given more details, which I see no particular
benefit to repeating. I think someone else even mentioned this, but it
is important enough to merit the repetition.

The guarantee you are talking about applies *ONLY* to allocatables.
Without that qualification, the statement is simply false. It is
trivially easy to leak memory using pointers. The example you showed
used an allocatable, but the above quote makes it sound like you think
there is actually some more general rule. Even if you happen to know
better, someone else reading the above won't know and might go away
thinking it was true just as you describe above. Heck, for all I know,
someone else made a simillar misstatement wherever you think you read
this, and that is misleading you.

As a smaller nit, deallocate is never called unless you have done
something like write your own subroutine named deallocate. "Calling"
applies only to subroutines. Deallocate is a statement - not a
subroutine. It can be "executed", or perhaps even a somewhat informal
"done", but not "called".
0 new messages