Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29283 Discussions

Allocatable array in a type - who will deallocate memory?

mtsagara
Beginner
728 Views
Hello, could you please help me with this code. I have a type that contains an allocatable array. I want to copy an intent(in) variable of that type in a subroutine to a either a local within the subroutine as in test_copy_my_type_2 or to a module private variable as in test_copy_my_type_1. I have two questions. 1) how do these statements work? my_private_type = input_type; temp_my_type = input_type; Do they perform a value copy or just pointer assigments? 2) If it is a value copy, do I have to free the allocated memory manually as in test_copy_my_type_1? Thank you in advance Emmanuil Tsagarakis module test_allocatable_types implicit none type my_type integer(4) num_values; real(8), dimension(:), allocatable :: arr_values; end type type (my_type), private:: my_private_type; contains subroutine test_copy_my_type_1(input_type) implicit none; type (my_type), intent (in):: input_type; my_private_type = input_type; if (allocated(my_private_type%arr_values)) deallocate(my_private_type%arr_values); end subroutine subroutine test_copy_my_type_2(input_type) implicit none; type (my_type), intent (in):: input_type; type (my_type) temp_my_type; temp_my_type = input_type; end subroutine end module test_allocatable_types program main use test_allocatable_types; implicit none type (my_type) t; t%num_values = 1000000; allocate(t%arr_values(t%num_values)); call test_copy_my_type_1(t); call test_copy_my_type_2(t); deallocate(t%arr_values); end program
0 Kudos
3 Replies
Steven_L_Intel1
Employee
728 Views

If you copy to a local variable in a procedure that has not been given the SAVE attribute, then the allocatable components will be automatically deallocated when the procedure returns. If you copy to a module variable, it will not get deallocated at all (until all storage is freed on program exit.)

So in your example, the copy made in test_copy_my_type_1 will not get deallocated. while the copy made in test_copy_my_type_2 will get deallocated as soon as that routine returns to the caller.

0 Kudos
mtsagara
Beginner
728 Views
Thank you for the quick responce, I do have some more questions. I am a mechanical engineer (not a "real" programmer) with C/C++ background. So this copy mechanism astonishes me! I can assume that the compiler always knows the size of the input variable even when it is a type with dynamicaly allocated members. Am I correct? One more question has to do with the stack size. Local variables with dynamicaly allocated members are allocated on the stack or on the heap? Will I have problems with the size of the stack in subroutine test_copy_my_type_2 if the size of the input variable is too big to fit? Finally as I noticed in this thread http://software.intel.com/en-us/forums/topic/363691 there is a problem with the deallocation of dynamicaly allocated nested types within a type that "you expect problem to be fixed in Update 4 (late June)." Does this means that until it is fixed I have to manualy deallocate all dynamicaly allocated nested types before their parent is deallocated? Thank you again for the responce Emmanuil Tsagarakis
0 Kudos
IanH
Honored Contributor III
728 Views

mtsagara wrote:

Thank you for the quick responce,

I do have some more questions.

I am a mechanical engineer (not a "real" programmer) with C/C++ background.
So this copy mechanism astonishes me!

If you are familiar with C++, the memory management aspect of allocatable arrays is similar to the memory management aspects of using a std::vector class member.

I can assume that the compiler always knows the size of the input variable even when it is a type with dynamicaly allocated members.
Am I correct?

The compiler may not know at compile time, but at runtime the (perhaps compiler supplied) internals of your program will know the size of the component.

One more question has to do with the stack size.
Local variables with dynamicaly allocated members are allocated on the stack or on the heap? Will I have problems with the size of the stack in subroutine test_copy_my_type_2 if the size of the input variable is too big to fit?

Note that stack/heap etc are implementation details.  Typically a local variable either goes on the stack or has space statically alloted for it as part of the loading of the executable image, depending on compiler options and procedure and variable attributes.  But for allocatable components the memory alloted for that variable only contains a descriptor that descripts^h^h^hbes where the data for the component is and things like its bounds and extent.  The data for the component is usually stored on the heap.  Again - this is similar to typical implementation of a std::vector in C++.

Operations on that component may then require temporary workspace on the stack - that can sometime cause issues.

Finally as I noticed in this thread http://software.intel.com/en-us/forums/topic/363691 there is a problem with the deallocation of dynamicaly allocated nested types within a type that "you expect problem to be fixed in Update 4 (late June)."

Does this means that until it is fixed I have to manualy deallocate all dynamicaly allocated nested types before their parent is deallocated?

That problem was to do with finalization - the calling of a programmer supplied procedure tied to the type of the component before the component was deallocated - a bit like a C++ destructor.  The actual deallocation of the component still happened, if I recall correctly.  For non-polymorphic stuff (variables and components declared with TYPE) I'm not aware of any current bugs.

0 Kudos
Reply