2016-12-04 3 views
4

I는 그 입력 조작을 서브 루틴으로 배열 슬라이스를 통과 말해?Fortran에서 배열을 분할하면 메모리에 복사본이 생성됩니까?</p> <pre><code>some_subroutine(a(:,1)) </code></pre> <p>가 변경된 원래 <code>a</code>의 섹션 또는 <code>a(:,1)</code> 일부 사본 변경된다

+0

gfortran의 경우 "-Warray-temporaries"또는 "-fcheck-array-temporaries"옵션은 임시 정보에 대한 정보를 얻는 데 유용합니다. 또한 실제 배열과 더미 배열의 첫 번째 요소의 주소를 어떻게 든 인쇄하여 동일한 메모리 (예 : c_loc() 또는 loc())를 가리키는 지 확인할 수 있습니다. – roygvib

답변

5

아마도 약간 해결 다른 답변의 몇 가지가있다 다른 (그러나 관련된) 점. 여기서 나는 그것들을 조화 시키려고 노력할 것이다.

Vladimir F's answer은 소위 카피 인/카피 아웃 메커니즘을 사용합니다. bfletch's answer 인수에 대한 최종 효과. 일반적

다음

integer i(2,2) 
i=0 
call dosomething(i(1,:)) ! Just to make it not contiguous. 

contains 
    subroutine dosomething(j) 
    integer j(2) ! or j(*), or j(:) 
    j=1 
    end subroutine 
end program 

효과는 어레이가 i1 설정된 일부 요소와 다른 0를 갖는다는 것이다. 따라서 yes : 임시 복사본이 있는지 여부에 관계없이 (호출 한대로) 호출 후에 관찰 할 수있는 것은 수정 된 실제 인수 자체라는 점입니다.

자연히 예외가 있습니다 : value 속성. 1 서브 루틴 위

subroutine doseomthing(j) 
    integer, value :: j(2) 
    j=1 
end subroutine 

다음 실제로 인수의 진정한 사본이 대신 같은 경우. 가짜 인수 j에 대한 수정은 i 섹션의 실제 인수에 반영되지 않습니다.


1이 현재 포트란을위한 것입니다. 태그가있는 Fortran 90에는이 기능이 없습니다.

+0

이제 OP의 실제 의도를 더 잘 읽었을 것 같습니다. 문제는 제목이 "사본을 메모리에 만듭니다"이지만 최종 질문은 원본이 수정되었는지 여부입니다. –

+0

저는 이것이 단지 스스로 대답하는 질문이라는 것을 눈치 챘지만 그 맥락에서 임시 복사본에 관해서는 확실히 말할 가치가 있습니다. 아마도 나는 또한 추가 할 수 있습니다 : 복사본을 만드는 슬라이싱에 관한 것은 없으며 여기서 슬라이스가 인수 일 때만 보겠습니다. 배열 슬라이스 할당에는 임시 복사본이 필요할 수도 있습니다. – francescalus

4

a 자체가 연속적인지, some_subroutine과 같은지에 따라 달라집니다.

a은 연속적이라고 가정 할 수도 있지만, a 자체가 가정용 모양 배열 또는 배열 포인터로 전달 된 일부 슬라이스 일 필요는 없습니다.

하더라도 asome_subroutine는 가정 된 형태 인수를 받아들이는 경우, 사본이 필요하지 않습니다되지 따라서 a(:,1)도하지 연속이며

subroutine some_sub(b) 
    real :: some_sub(:)