Ошибка после размещения компонентов массива в массиве производного типа

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,

Другие вопросы по тегам