让我考虑一个返回allocatable
数组的函数。是否应该在赋值之前分配保存结果(函数外部)的数组变量?
例如,考虑以下程序
program mem
implicit none
interface
function get_matrix() result(res)
real(kind=kind(0.d0)), allocatable :: res(:,:)
end function get_matrix
end interface
real(kind=kind(0.d0)), allocatable :: w(:,:)
allocate(w(2,2)) ! Is this necessary?
w=get_matrix()
deallocate(w)
end program mem
function get_matrix() result(res)
real(kind=kind(0.d0)), allocatable :: res(:,:)
allocate(res(2,2))
res = 0.d0
res(1, 1) = 1.d0
res(2, 2) = 1.d0
end function get_matrix
根据this和thisres
,为结果分配的数组get_matrix
一旦超出范围就会被释放。
w
对主程序中未分配变量的赋值会延长结果的范围get_matrix
吗?换句话说,如果我allocate(w(2,2))
在主程序中省略,我会得到一个未定义的行为吗?
使用and 选项省略allocate(w(2,2))
和编译会给出以下警告gfortran 9.2.0
-Wall -std=f2008
mem.f90:13:0:
13 | w=get_matrix()
|
Warning: ‘w.offset’ is used uninitialized in this function [-Wuninitialized]
mem.f90:13:0: Warning: ‘w.dim[0].lbound’ is used uninitialized in this function [-Wuninitialized]
mem.f90:13:0: Warning: ‘w.dim[0].ubound’ is used uninitialized in this function [-Wuninitialized]
mem.f90:13:0: Warning: ‘w.dim[1].lbound’ is used uninitialized in this function [-Wuninitialized]
mem.f90:13:0: Warning: ‘w.dim[1].ubound’ is used uninitialized in this function [-Wuninitialized]
mem.f90:13:0:
13 | w=get_matrix()
|
Warning: ‘w.dim[0].lbound’ may be used uninitialized in this function [-Wmaybe-uninitialized]
mem.f90:13:0: Warning: ‘w.dim[0].ubound’ may be used uninitialized in this function [-Wmaybe-uninitialized]
mem.f90:13:0: Warning: ‘w.dim[1].lbound’ may be used uninitialized in this function [-Wmaybe-uninitialized]
mem.f90:13:0: Warning: ‘w.dim[1].ubound’ may be used uninitialized in this function [-Wmaybe-uninitialized]
mem.f90:13:0: Warning: ‘w.dim[0].ubound’ may be used uninitialized in this function [-Wmaybe-uninitialized]
mem.f90:13:0: Warning: ‘w.dim[0].lbound’ may be used uninitialized in this function [-Wmaybe-uninitialized]
mem.f90:13:0: Warning: ‘w.dim[1].ubound’ may be used uninitialized in this function [-Wmaybe-uninitialized]
mem.f90:13:0: Warning: ‘w.dim[1].lbound’ may be used uninitialized in this function [-Wmaybe-uninitialized]
但是,使用 运行程序valgrind
以及使用 、 或 进行编译-fbounds-check
不会-fsanitize=address
产生-fsanitize=leak
任何错误。此外,最后的指令deallocate(w)
不会使程序崩溃,表明w
包含由分配的内存get_matrix
,因此不需要w
在主程序中分配。
同时,包含allocate(w(2,2))
在代码中会抑制编译器警告。尽管给人的印象是相同的内存被分配了两次,valgrind
但不会报告内存泄漏,事实上,报告的内存使用情况完全相同。
allocatable
将数组存储为函数结果的正确方法是什么?是否有必要w
在存储结果之前进行分配get_matrix
?