1

コンテクスト

以下に掲載されているおもちゃのFortranコードは、2つのポインター関数を呼び出します。つまり、両方の関数がポインタを返します。実際、これらは両方とも配列ポインターです。どちらも同じことを行おうとします。つまり、1、2、3の3つの要素を持つ整数配列を参照する整数配列ポインターを返します。最初の関数は、ポインター割り当て演算子(=>)を使用して、関数ポインターをデータを保持する割り当て可能な配列。2番目の関数は、データを格納するために、ポインタを介して動的メモリのブロックを直接割り当てます。呼び出し側プログラムは、返された配列の要素を出力するだけです。

これが私が奇妙だと思うものです。

  1. の結果を指すaと、結果function1は正しくありません。の最初の要素はa「clobbered」のように見えます :ahas 0、、。23
  2. の結果を指すbと、function2結果は正しいです。 、、bを取得します。123
  3. それでも見知らぬ人は、それが正しくなるよう に変化を指し示したbの結果を指し示します。次に、、、。_function2 afunction1 aa123

質問

なぜこれが発生するのですか?より正確には、割り当て可能な配列へのポインターを返すポインター関数が、呼び出し元のその配列の最初の要素をクローバーするのはなぜですか?さらに正確に言えば、あるポインター()を指すbと、別のポインター()に副作用が生じるのはなぜaですか。ターゲットは、相互作用しないように記述されたさまざまな関数から取得されます。

警告

この動作は、Ubuntu(Jaunty)でIntelラップトップを実行しているGNUFortranコンパイラv.4.3.3を使用して取得します。結果は異なる場合がありますが、それでもなお興味深い場合があります。最後に、いつものように、それは私の側のオペレーターエラーである可能性があり、それは少なくとも私にとって興味深いでしょう。

コード

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

1 に答える 1

4

function1の変数配列はローカル変数です。「save」属性なしで宣言されているため、永続的ではなく、関数の終了時に未定義になります。配列のアドレスをfunction1に割り当て、このアドレスを「保持」しますが、関数の終了後に変数が未定義になると、アドレスは意味を持ちません。可能性のある実装はその配列ですfunction1のがスタックに配置され、function1が戻ったときに、スタックのその領域が他の用途のために解放されます。しかし、これは可能性のある実装の推測にすぎません。重要な点は、変数が未定義になった後はポインター値を使用できないということです。割り当て可能な変数は、「save」属性で宣言しない限り、スコープ外になると自動的に割り当てが解除されます。

于 2009-10-17T02:10:54.840 に答える