use*_*489 5 fortran allocation jagged-arrays
在我的Fortran代码中,我想使用具有多级分配的锯齿状数组.我的意思是一个示例代码
module nonsquare_matrix_mod
implicit none
type :: nonsquare_matrix
integer :: d
real*8, dimension(:), allocatable :: vector
end type nonsquare_matrix
type(nonsquare_matrix),dimension(:),allocatable :: mymatrix
end module nonsquare_matrix_mod
program nonsquare_matrix_test
use nonsquare_matrix_mod
implicit none
integer, parameter :: max_size=50
integer :: i
allocate(mymatrix(max_size))
do i=1,max_size
allocate(mymatrix(i) % vector(i))
end do
print *, "allocated"
end program
Run Code Online (Sandbox Code Playgroud)
我想实现这种编程策略以节省内存.我知道这个例子中保存的内存不是太大,但对于我的实际项目,我正在使用更大的数据结构.我想知道这种编程习惯是否存在任何危险,例如数据没有连续存储或者更容易出现内存泄漏.或者这是一种节省内存而没有很多缺点的有用方法吗?谢谢.
由于您只使用可分配的数组,因此在使用指针时可能没有任何内存泄漏.锯齿状阵列是否是解决问题的合理解决方案,在很大程度上取决于数据的结构.需要注意的几点:
确实,你的阵列不会是连续的.当您访问后续行时,这有几个含义,例如更糟糕的缓存行为.
您必须allocate单独分配每一行.如果它经常发生(例如在循环内),那可能是一个问题,因为分配是一个相当"慢"的操作.
如果数组中的行的大小确实非常不同(并且没有太多行),则可能会节省大量内存.
如果行的长度是在它们创建时设置的,而不是之后改变的(并且你最好猜测你将在整个数组中有多少元素),你可以分配一个大的缓冲区数组,放在哪里在行中,以及一个索引数组,其中包含缓冲区数组中该行的第一个元素的位置:
program nonsquare_matrix_test
implicit none
integer, parameter :: dp = kind(1.0d0)
integer, parameter :: maxlines = 50
integer, parameter :: maxelements = 5000
real(dp), allocatable :: buffer(:)
integer, allocatable :: rowindex(:)
integer :: ii
allocate(buffer(maxelements))
allocate(rowindex(maxlines + 1))
rowindex(1) = 1
do ii = 1, maxlines
rowindex(ii + 1) = rowindex(ii) + ii
end do
! ...
! Omitting the part which fills up the array
! ...
! Accessing a given line (e.g. line 5)
print *, "Content of line 5:"
print *, buffer(rowindex(5):rowindex(6)-1)
end program nonsquare_matrix_test
Run Code Online (Sandbox Code Playgroud)