Ошибка после размещения компонентов массива в массиве производного типа
module sdata
integer, parameter :: nblock = 2
TYPE block_info
REAL, ALLOCATABLE :: w(:)
END TYPE block_info
TYPE(block_info), TARGET :: block(nblock)
end module sdata
module variable
use sdata
REAL, POINTER :: w(:)
contains
!.............................
subroutine set_current(n)
nullify(w)
allocate(w(10))
w(1:10) => block(n)%w(1:10)
end subroutine set_current
!.............................
end module variable
subroutine make_sth
use variable
use sdata
real,allocatable,dimension(:)::wm,wp,ww
integer n
allocate(wm(5),wp(5),ww(5))
do n = 1,nblock
block(n)%w(1:10) = (/ 1.,2.,3.,4.,5.,6.,7.,8.,9.,10./)
call set_current(n)
wp(1:5) = w(1:5)
wm(1:5) = w(6:10)
ww = wp + wm
do i = 1,5
print*, 'block = ',n,'ww = ',ww(i)
enddo
enddo
end subroutine make_sth
program main
use variable
use sdata
allocate(block(nblock)%w(10))
call make_sth
end program main
Вот мой вопрос Для nblock=1 код отлично работает, однако, если я увеличу nblock т.е. до 2 это дает проблемы с памятью. Как это возможно?
2 ответа
Давайте посмотрим на распределение компонентов массива производного типа. В частности строка в основной программе
allocate(block(nblock)%w(10))
Кажется, это не то, что вы думаете.
Здесь происходит то, что компонент w
элемента nblock
из block
выделено. Это не значит, что nblock
компоненты block
все выделены на этот размер. когда nblock
равно 1, эффект тот же: нет проблем.
Вам нужно выделить компонент каждого элемента индивидуально. Это имеет смысл, так как часто требуется, чтобы каждый элемент имел компоненты разного размера или изменяющийся статус распределения. Есть несколько подходов к этому, но я не буду освещать их здесь: для этого есть другие вопросы.
+ Изменить
allocate(block(nblock)%w(10))
в
do i = 1, nblock
allocate(block(i)%w(10))
end do
В текущем коде вы выделяете только один элемент block
: или block(1)%w(10)
если nblock=1
или же block(2)%w(10)
если nblock=2
, С модификацией я предлагаю вам выделить массив w
внутри каждого элемента block
,