下面一段代码中,我们在模块m_dat中定义了一个包含动态数组的结构体dat,结构体dat具有方法load,用于分配内存以及初始化变量。主程序中两次调用load方法,对结构体中动态数组进行内存分配和赋值,并输出结果。
01 | module m_dat |
02 | type dat |
03 | real , allocatable :: a ( : ) |
04 | contains |
05 | procedure , pass :: load |
06 | end type |
07 | contains |
08 | integer function load ( obj ) |
09 | class ( dat ) , intent ( inout ) :: obj |
10 | integer :: k = 0 |
11 | k = k +1 |
12 | allocate ( obj.a ( k ) ) |
13 | obj.a = k |
14 | load = 0 |
15 | end function |
16 | end module |
17 | |
18 | program y |
19 | use m_dat |
20 | type ( dat ) d |
21 | integer i |
22 | |
23 | i = d.load ( ) |
24 | print * , d.a ( 1 ) |
25 | pause |
26 | |
27 | i = d.load ( ) |
28 | print * , d.a ( 1 ) |
29 | pause |
30 | end |

我们对代码中的load方法作一些修改。先检测数组是否已分配,如果已分配内存,则将其释放掉,然后再分配。修改后代码如下:
1 | integer function load ( obj ) |
2 | class ( dat ) , intent ( inout ) :: obj |
3 | integer :: k = 0 |
4 | k = k +1 |
5 | if ( allocated ( obj.a ) ) deallocate ( obj.a ) |
6 | allocate ( obj.a ( k ) ) |
7 | obj.a = k |
8 | load = 0 |
9 | end function |
代码修改后,程序便能正确执行,结果如下图。

基于本文的主旨,我们讨论另一种情况。修改load方法的代码:
可以看出,相对于文章开头的代码,我们只是将形参obj的intent属性由inout改为了out,而并未添加检测数组是否已分配的操作。程序能够正确执行,运行结果与上图一致。
1 | integer function load ( obj ) |
2 | class ( dat ) , intent ( out ) :: obj |
3 | integer :: k = 0 |
4 | k = k +1 |
5 | allocate ( obj.a ( k ) ) |
6 | obj.a = k |
7 | load = 0 |
8 | end function |
结论:如果函数中形参obj为包含动态数组的结构体变量,执行该函数时,如果obj具有intent(inout)属性(缺省), 对应的实参会被原样传递给obj;如果具有intent(out)属性,那么在,将首先释放结构体变量中动态数组所占用的内存空间。