2009-10-16 5 views
1

컨텍스트

아래에 게시 된 장난감 포트란 코드는 두 개의 포인터 기능을 호출합니다. 즉, 두 함수 모두 포인터를 반환합니다. 사실, 둘 다 배열 포인터입니다. 그들은 둘 다 세 가지 요소, 1, 2 및 3을 갖는 정수 배열을 참조하는 정수 배열 포인터를 반환하는 동일한 작업을 시도합니다. 첫 번째 함수는 포인터 할당 연산자 (=>)를 사용하여 데이터를 보관 유지하는 할당 가능한 배열 두 번째 함수는 데이터를 저장하기 위해 포인터를 통해 다이나믹 메모리 블록을 직접 할당합니다. 호출 한 프로그램은 반환 된 배열의 요소를 출력합니다.Fortran 포인터 함수 :이 코드의 동작은 함수 호출 순서에 따라 다릅니다.

내가 이상한 것을 발견했습니다.

  1. a의 결과가 function1 인 경우 결과가 올바르지 않습니다. a의 첫 번째 요소는 "clobbered"인 것처럼 보입니다. a0, 2, 3입니다.
  2. bfunction2의 결과로 지정하면 결과가 정확합니다. b1, 2, 3이됩니다.
  3. 낯선 여전히는 function1a 가리키는 후 function2의 결과 b 가리키는 것은 올바른가되도록a 그러한 변화. a1, 2, 3입니다.

는 왜가 발생 질문? 좀 더 정확히 말하면, 할당 가능한 배열에 대한 포인터를 반환하는 포인터 함수가 호출자에 대한 해당 배열의 첫 번째 요소를 왜 잡는가? 좀 더 정확하게 말하면, 한 포인터 (b)를 가리키는 것이 다른 포인터 (a)에 부작용을 일으키는 이유는 무엇입니까? 여기서 대상은 서로 상호 작용하지 않도록 작성된 서로 다른 기능에서 나온 것입니까?

주의 사항은

우분투 (말쑥한)와 인텔 노트북을 실행되는 GNU 포트란 컴파일러 v.4.3.3을 사용하여이 동작을 얻을. 결과가 다를 수 있으며, 이는 여전히 더 흥미로울 수 있습니다. 마지막으로, 언제나 그렇듯이 내 부분에서는 조작자 오류 일 수 있습니다. 이는 나에게 흥미로울 것입니다.

코드

배열 기능 1의 로컬 변수
program main 
    implicit none 
    integer, dimension(:), pointer :: a, b 
    integer :: i 
    a => function1() 
    b => function2() 
    do i = 1, 3 
    print *, a(i) 
    end do 
    ! do i = 1, 3 
    ! print *, b(i) 
    ! end do 
contains 
    function function1() 
    integer, dimension(:), allocatable, target :: array 
    integer, dimension(:), pointer :: function1 
    allocate(array(3)) 
    array(1) = 1 
    array(2) = 2 
    array(3) = 3 
    function1 => array 
    end function function1 

    function function2() 
    integer, dimension(:), pointer :: function2 
    allocate(function2(3)) 
    function2(1) = 1 
    function2(2) = 2 
    function2(3) = 3 
    end function function2 
end program main 

답변

4

변수 - 그것이 "저장"속성없이 선언되어 있기 때문에, 그것은 지속되지 않으며 함수가 종료되면 정의되지 않습니다. 배열의 주소를 function1에 할당하고이 주소를 "유지"하지만 변수가 함수에서 나오면 변수가 정의되지 않게되면 주소는 의미가 없습니다. 가능한 구현은 function1의 배열이 스택에 배치되고 function1이 반환 될 때 스택의 해당 영역이 다른 용도로 해제된다는 것입니다.그러나 이는 구현 가능성이있는 추측에 불과합니다. 핵심은 변수가 정의되지 않은 상태에서 포인터 값을 사용할 수 없다는 것입니다. 할당 가능 변수는 "save"속성을 사용하여 선언하지 않는 한 자동으로 할당 범위를 벗어납니다.

+0

Perfect! 고맙습니다! –