2016-11-17 2 views
0

Я не очень хороший программист, и я просто пытаюсь взаимодействовать с моделью, которая предоставляет данные в качестве указателей. Эти указатели передаются через несколько подпрограмм перед их записью. Я не уверен, как это сделать, чтобы избежать утечек памяти.Правильный способ передать указатели на многие подпрограммы

Предположим, у меня есть указатель на массив A, который передается нескольким подпрограммам перед записью, как обрабатывать объявления, распределения и освобождения?

module data 

implicit none 
contains 

subroutine s1(a) 
real, pointer, intent(out) :: a(5,5) 

call s2(a) 
end subroutine s1 

subroutine s2(a) 
real, pointer, intent(out) :: a(5,5) 
integer :: i 

do i = 1,5 
    a(:,i) = 5.0 
end do 
end subroutine s2 
end module data 

Program test 
use data, only : s1, s2 
real, pointer, dimension(:,:) :: A => NULL() 
allocate(A(5,5)) 
call s1(A) 
write(*,*) A 
deallocate(A) 
end Program test 
+1

Я не совсем уверен, что вы просите, но если у вас есть проблемы с кодом это скорее всего связано с 'умыслом (из)' атрибута этих указателей. См. Например, [этот связанный вопрос] (https://stackoverflow.com/q/29737367). Или так называемая _explicit shape_ nature (которая конфликтует с указателем). – francescalus

+1

Вам нужно указать размер только один раз. В подпрограммах вы должны объявить как: 'real, pointer, dimension (:, :), intent (out) :: a'. После 'deallocate (A)', если вам больше не нужен указатель, вы можете «аннулировать (A)» –

ответ

1

Пожалуйста, обратите внимание, что ваш код не Fortran 90. Атрибут intent для холостых (формальных) аргументов, которые являются указателями был введен в Fortran 2003

intent относится к статусу ассоциации указателя, а не его цели. Кроме того, если аргумент является производным типом с компонентами указателя , то intent применяется к самому типу объекта, а не к целям указателей. То есть, если, например, используется intent(in), область данных, что указатель предназначен может быть изменен:

module MyType_mod 

    implicit none 
    private 

    type, public :: MyType 
    integer, pointer :: ptr(:) 
    contains 
    procedure :: sub => my_type_sub 
    end type MyType 

contains 

    subroutine my_type_sub(self) 
    ! Dummy argument 
    class(MyType), intent(in) :: self 

    ! The following is perfectly legal, 
    ! even though intent(in) was specified 
    self%ptr = 42 

    end subroutine my_type_sub 

end module MyType_mod 

program main 

    use MyType_mod, only: & 
     MyType 

    implicit none 

    type(MyType) :: foo 
    integer  :: alloc_stat 

    allocate(integer :: foo%ptr(100), stat=alloc_stat) 
    call foo%sub() 

end program main 

Даже если не требуется, в случае, например, в предыдущем примере, то лучше состояние intent(inout), чтобы указать читателю, что происходит изменение данных.

На другой ноте, вы можете найти этот ответ полезным Fortran subroutine returning wrong values

+0

Утверждение «Я не очень хороший программист», кажется, противоречит желанию использовать указатели. И даже действительно хорошие программисты часто избегают указателей по разным причинам. Трудно понять, почему вы хотите использовать указатели из предоставленного кода. Я бы пересмотрел, нужны ли вам указатели или нет, хотя использование указателей - интересный вопрос. – Holmz

Смежные вопросы