2013-07-02 7 views
0

У меня возникла проблема с передачей массивов между модулями и основной программой. Модуль и основная программа прекрасно компилируются с использованием gfortran. Однако при выполнении файлов .exe файл сталкивается с проблемой и закрывается. Это происходит только тогда, когда массив имеет неизвестный размер (и его размер должен быть выделен). Я включил небольшой фрагмент кода, который иллюстрирует эту проблему:Fortran 95 - Передача массивов между модулями

Как это работает: Пользователю предлагается целое число «я», который определяет размер квадратной матрицы. Это целое число передается функции модуля, которая создает матрицу и возвращает ее в основную программу. Затем матрицу печатают на экране.

Основная программа в одном файле:

program main1 
use module1 
implicit none 
integer :: i 
real,allocatable :: a(:,:) 

write(*,*)'Input the size of the square matrix' 
read(*,*)i 

allocate(a(i,i)) 
a = function1(i) 

write(*,*) 'The square matrix a=' 
write(*,*) a 

deallocate(a) 
end program main1 

и модуль в отдельном файле:

module module1 

contains 
function function1(i) 
real, allocatable,dimension(:,:) :: function1 
integer :: i 

allocate(function1(i,i)) 
function1 = 1.0 

deallocate(function1) 
end function function1 
end module 

Спасибо за вашу помощь, ребята!

ответ

4

Вы освобождаете массив function1, прежде чем функция сможет вернуть его в основную программу. Устраните линию deallocate(function1), и она отлично работает.

Ну, не совсем отлично, если вы хотите получить квадратную матрицу. Вы должны иметь заявление на запись в качестве

do j=1,i 
    write(*,*) a(:,j) 
    enddo 

иметь выход как-то вроде

1.000 1.000 1.000 
    1.000 1.000 1.000 
    1.000 1.000 1.000 

Обратите внимание, что если вы обеспокоены function1 занимает пространство памяти, написать подпрограмму, которая освобождает его и называют его сразу после установки a=function1(i)

+1

Я не понимаю вашего последнего предложения, кажется, что массив, выделенный внутри 'function1', копируется в' a'. Я понимаю, что после вызова 'function1' массив, выделенный функцией, доступен как переменная' a', 'function1' не занимает лишнюю память. –

+0

Я думал, что, поскольку он выделяет массив там, для этого потребуется память. Я полагаю, что это не так? –

+0

Как я (и еще до сих пор!) понять ситуацию, когда функция возвращает выделение памяти вызывающей подпрограмме, которая вызывает выделенную память 'a'. Существует только одно распределение памяти. –

3

@ Ответ Кайла указывает на проблему, которая приводит к сбою вашей программы. Но есть еще одна тонкая проблема с вашим кодом, о котором вы должны знать, хотя он не может быть прямой ошибкой.

Если у вас есть современный компилятор и правильные параметры, то оператор распределения в вашем вызывающем коде не нужен. То есть вам не нужно выделять переменную a перед вызовом function1, Fortran автоматически назначит a размеру, который возвращается function1. Конечно, параметр компилятора зависит от того, какой компилятор вы используете. Возможно, вам потребуется задействовать семантику Fortran 2003 или автоматическое распределение переменных lhs или что-то подобное.

Это вопрос, вы должны знать, потому что, если вы используете автоматическое распределение (или если ваш компилятор реализует его по умолчанию), назначая результат вызова function1 к a будет перераспределять a.

+1

Вы абсолютно правы в том, что оператор allocate является излишним, но * re * -распределение происходит только в том случае, если размер параметра lhs (или отложенной длины или динамического типа, если это необходимо) не соответствует. В противном случае вы можете сломать код F95. – IanH

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