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

Question about deallocation of pointers

Ave_Phoenix
Beginner
2,105 Views
I am trying nullify a pointer in case of:

1) a pointer has been only pointed to something
2) a pointer has been previously allocated

In (1) a nullify statement is enough, in (2) a deallocate statement will be also enough.

What I want to do is to nullify a pointer (and free memory if necessary) at once.

A piece of code like this would work for either (1) or (2) for a pointer p

if ( associated( p ) ) then
deallocate( p , stat = status )
if ( status /= 0 ) nullify( p )
end if

If (1) holds, the deallocate statement will be succesfully performed and status = 0.
If (2) holds, I suppose the deallocation statement causes an error with status /= 0, and then p is nullified.

The problem is that execution is aborted.

Is this behaviour normal? An example program is written below.

Thanks in advance.

==========================

program main

implicit none

real , pointer :: a1 => null()
real , pointer :: a2 => null()
real , target :: b2

integer :: status
character( len = 1000 ) :: error

allocate( a1 )
deallocate( a1 , stat = status )
if ( status /= 0 ) nullify( a1 )

b2 = 1.0
a2 => b2
if ( associated( a2 ) ) then
deallocate( a2 , stat = status )
if ( status /= 0 ) nullify( a2 )
end if

end program main

===========================
0 Kudos
8 Replies
mecej4
Honored Contributor III
2,105 Views
I do not see a problem with your short program although, in a larger piece of code you should check for the success of ALLOCATE, by including a STAT=stat clause, before using the allocated object.

Secondly, in the following construct

if ( associated( p ) ) then
deallocate( p , stat = status )
if ( status /= 0 ) nullify( p )
end if

the first line is illegal if the pointer variable p is undefined. In your example you initialized pointers to nil(), but do you do the same in your large program?
0 Kudos
Ave_Phoenix
Beginner
2,105 Views
Thanks for your soon answer.

Yes, you are right, I should check the sucess of ALLOCATE by including a STAT=stat clause, but I did not just to show the example.
In the other hand, I use to initialize pointers to null() in large programs, so there should be no problem in the first line you mentioned.

The reason of my question is that I have a derived type where the fields are pointers. So, a user could eventually allocate the pointer, or just point to something. I want to have a final subroutine to avoid memory leaks.
But how to decide if a pointer has been allocated or pointed?

Best regards.

German

0 Kudos
Steven_L_Intel1
Employee
2,105 Views
Unless you take care to NULLIFY the pointer initially and after deallocation, you can't reliably tell. If however you use an ALLOCATABLE variable instead of POINTER you can reliably test it with ALLOCATED.
0 Kudos
Ave_Phoenix
Beginner
2,105 Views
Is it possible to give the ALLOCATABLE attribute to a scalar variable? I tested it for intel compiler and the answer is yes.
But this is an extension of intel compiler or is it in the standard?
For g95 and gfortran this is not permitted, but I wonder if the reason is that is not implemented yet.
0 Kudos
Steven_L_Intel1
Employee
2,105 Views
That's a standard Fortran 2003 feature. We also support deferred-length allocatable character variables:

character(:), allocatable :: string

You can assign to the variable and it will change to the length of the value you assigned to it, or allocate it to a desired length:

allocate (character(10)::string)
0 Kudos
Ave_Phoenix
Beginner
2,105 Views
Thanks for your answer, very clear.
0 Kudos
jimdempseyatthecove
Honored Contributor III
2,105 Views
character(:), allocatable :: string
allocate (character(10)::string)

Cool.
How about

character(:), allocatable :: bunchOstrings(:)
allocate (character(10)::bunchOstrings(200))

?

Jim
0 Kudos
Steven_L_Intel1
Employee
2,105 Views
Yes, that works, but all of the elements will be 10 bytes and the length won't change on an assignment, because the automatic reallocation only applies to whole variables (or derived type components), not array elements.

You could do this:

[fortran]type vstring_type
  character(:),allocatable :: vs
end type vstring_type

type(vstring_type), allocatable :: vs_array(:)

allocate (vs_array(10))
 do i=1,size(vs_array)
  vs_array(i)%vs = repeat('*',i)
  end do

 do i=1,size(vs_array)
  write(*,'(A,A)') vs_array(i)%vs,'/'
  end do
end[/fortran]
Note that I did not explicitly allocate the elements of vs_array - that gets done implicitly on assignment.

When compiled and run you get this:

[plain]*/
**/
***/
****/
*****/
******/
*******/
********/
*********/
**********/[/plain]
0 Kudos
Reply