5

私の 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

メモリを節約するために、このプログラミング戦略を実装したいと考えています。この例で保存されたメモリがそれほど大きくないことはわかっていますが、実際のプロジェクトでは、はるかに大きなデータ構造を扱っています。このプログラミング手法には、データが連続して格納されない、メモリ リークが発生しやすいなどの危険性があるかどうか疑問に思っていました。それとも、これは多くの欠点を伴わずにメモリを節約する便利な方法ですか? ありがとう。

4

1 に答える 1

6

割り当て可能な配列のみを使用しているため、ポインターを使用する場合に発生する可能性のあるメモリ リークは発生しません。ジャグ配列が問題の合理的な解決策であるかどうかは、データの構造に大きく依存します。注意すべきいくつかの点:

  • 実際、あなたの配列は連続していません。これには、後続の行にアクセスするときのキャッシング動作の悪化など、いくつかの意味があります。

  • すべての回線を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
于 2013-02-13T19:27:52.440 に答える