Как создать дескриптор для структуры / массива внутри подпрограммы FORTRAN? - PullRequest
1 голос
/ 07 августа 2011

Мне нужно создать дескриптор для довольно сложной структуры (здесь вместо "real a (2)") в подпрограмме, а затем только передать дескриптор / указатель на основную подпрограмму.Мне также нужно иметь возможность создавать столько необходимой структуры.Проблема в том, что структура данных будет освобождена после того, как указатель вернется в main.Вот моя попытка:

  program main
  implicit none

  integer i, j
  real a(2) ! This can be a complicated structure

  a=(/1.1,2.2/)
  call myalloc(a,i)

  a=(/3.1,4.2/)
  call myalloc(a,j)

  call myprint(i)      
  call myprint(j)

  stop
  end

c -----------------------------------

  subroutine myalloc(a,i)
  implicit none

  real, pointer :: i(:) ! If I add "save" attribute I will get an error
  real, target :: a(2)

  allocate(i(2))
  i => a

  return
  end 

c --------------------------------

  subroutine myprint (i)
  implicit none

  real, pointer :: i(:)

  print *, i

  return
  end

c ---------------------------------

В результате получаются некоторые значения мусора: 3.93764868E-43 1.40129846E-45

Или я получу: В строке 41 файла test.f (unit = 6, file = 'stdout') Внутренняя ошибка: list_formatted_write (): неверный тип

Любая помощь будет принята с благодарностью.

1 Ответ

1 голос
/ 07 августа 2011

В этом коде так много неправильного, что почти слишком сложно дать конструктивный ответ.

Если я понимаю, что вы пытаетесь сделать, подпрограмма myalloc должна действовать как своего рода конструктор копирования - выделять память на предоставленный указатель, а затем копировать содержимое инициализирующего аргумента в выделенную память. Итак, ключевая ошибка в вашем myalloc - это две строки:

  allocate(i(2))
  i => a

Здесь вы сначала выделяете память для указателя i, затем присваиваете i, чтобы указать a. Зачем вообще выделять меня в этом случае? Я полагаю, это ближе к тому, что вы пытаетесь сделать:

subroutine myalloc(a,b,n)
  implicit none

  real, dimension(n) :: a
  real, pointer,dimension(:) :: b
  integer :: n

  allocate(b(n))
  b = a ! This copies the contents of the array a to the allocation for b

  return
end 

Тогда в вашей основной программе есть ряд необъяснимых вещей. Почему i и j объявлены как целые числа? Конечно, они должны быть указателями на реальные массивы, если вы хотите передать их вашему myalloc, выполнить операцию выделения / копирования, а затем напечатать их? Если дело обстоит так, то замена вашего основного на что-то вроде этого должно быть ближе к тому, что вы пытаетесь сделать:

program main
    implicit none

    interface
        subroutine myalloc(a,b,n)
        real,dimension(n) :: a
        real,pointer,dimension(:) :: b 
        integer :: n
        end subroutine myalloc

        subroutine myprint(i)
        real,pointer,dimension(:) :: i
        end subroutine myprint
    end interface

    real,pointer,dimension(:) :: i, j
    real :: a(2)

    a=(/1.1,2.2/)
    call myalloc(a,i,2)

    a=(/3.1,4.2/)
    call myalloc(a,j,2)

    call myprint(i)
    call myprint(j)

    stop
end

С этими изменениями вы должны получить это при запуске:

$ ./pointer
   1.100000       2.200000    
   3.100000       4.200000    

Это ближе к тому, что вы ожидали получить?

...