0

以前の投稿をよく見ましたが、このトピックがカバーされているとは思いません。誰かが助けてくれることを願っています. 私は fortran 2003 でコードを書き、ifort を使用しています。操作する必要がある次の型があり、必要な柔軟性を与えるように設計しています。

module parameters    

double precision, target :: cur_x(3)    

    type fundamental
            double precision, pointer   ::  x => null()
    end type fundamental

    type, extends(fundamental) :: ion
            class(fundamental), pointer ::  core => null()
     end type ion

SAVE
end module parameters

リストの前のものを次のコアとして使用することにより、粒子のリンクされたリストのようなものを構築するという考えです。実際には、「ファンダメンタル」への多数の拡張があり、そのすべてが他の粒子の「コア」になる可能性があることに注意してください。かなり複雑な方法でそれらのサブセットをアドレス指定するため、計算された量 x を物理メモリ内の配列に一緒に配置したいので、cur_x への別のポインターのセットを使用したい

コードの初期化は次のようになり、診断行をいくつか追加しました。

use parameters

    type(fundamental), target :: electron, proton
            type(ion), target :: hydrogen

    write(*,*)associated(electron%x),associated(proton%x), &
                   & associated(hydrogen%core),associated(hydrogen%core%x)

        electron%x => cur_x(1)

        hydrogen%core => proton
        proton%x => cur_x(2)
        hydrogen%x => cur_x(3)

        cur_x = 1.0

    write(*,*)electron%x,proton%x,hydrogen%x,hydrogen%core%x

印刷する

F F F T
1.0 1.0 1.0 <garbage>

proton%x と Hydrogen%core%x がメモリ内の同じアドレス (cur_x(2)) であると予想される場合。だから私は2つの質問があります

  1. すべてのポインターを null に初期化しました。associated(hydrogen%core%x) が真になるのはなぜですか? コードの先頭でこのポインターを無効にしようとすると、一貫性のない結果が得られます。使用して

    nullify(hydrogen%core%x)
    

    セグメンテーション違反が発生します。実行中

    hydrogen%core%x => null()
    

    コードの実行を許可しますが、associated(hydrogen%core%x) は true のままです

  2. fortran の驚くべきエラーのこの要約で示唆されているように、親から子へのポインターのリストを関連付けることを確認しました。proton%x は機能しているが、hydrogen%core%x がガベージを与えるという事実は、私には理解できないものです。

この問題を回避することはできますが、より複雑な計算に必要な一般性が犠牲になります。また、ここで何が問題なのかを理解したいと思います。

ご協力いただきありがとうございます!ジム

編集:さまざまなものの「ターゲット」プロパティに追加されました。これは常にコードに含まれていることに注意してください。この投稿に転送するときにそれらを忘れてしまいました

編集:明確にするために、上記のコードに関する私の主な問題は、最初の書き込み後に関連付けコマンドを実行しても、最後の書き込みコマンドが Hydrogen%core%x の初期化されていない出力を与えることです。型定義でコアを null として初期化しても、問題があるようです。コードの先頭でそれを無効にしようとすると、プログラムがクラッシュします。

4

2 に答える 2

2

基本的な問題は、hydrogen%core関連付けられていないことです。したがって、の効果associated(hydrogen%core%x)は不確定です。ポインタが関連付けられていない場合、たとえばメモリ内の既存の派生型インスタンスの代わりにポイントを指す場合、x派生型ポインタ()のフィールド()にアクセス/クエリすることはできません。コンパイラがコードを生成する場合がありますが、試してみてもすぐにはクラッシュしませんが、ランダムなメモリアドレスですでに一部のデータを上書きしている可能性があるため、その後に行われることはすべて不確定です。hydrogen%corenull()

実際、私はさまざまなコンパイラを使用してコードの自己完結型バージョン(以下を参照)をコンパイルしましたが、最初の書き込みステートメントですぐにsegfaultが発生しました。適切なチェックオプションを使用すると、バイナリの1つが、関連付けが解除されたポインタを参照している理由を報告しますhydrogen%core。問題のあるクエリをコメントアウトするとassociated()(以下のコードのように)、すべてのバイナリが正常に実行されます。

また、変数electronprotonにはターゲット属性が必要であることに注意してください。そうでない場合、コードはまったくコンパイルされません。コンパイラが文句なしにコードをコンパイルする場合は、おそらく別のコードに変更することを検討する必要があります。

  module parameters    
  implicit none
  save

  type :: fundamental
    double precision, pointer ::  x => null()
  end type fundamental

  type, extends(fundamental) :: ion
    class(fundamental), pointer ::  core => null()
  end type ion

end module parameters

program test
  use parameters
  implicit none

  type(fundamental), target :: electron, proton
  type(ion) :: hydrogen
  double precision, target :: cur_x(3)

  ! If you remove the comment in the next statement, the program will be indeterministic
  ! and probably crash.
  write(*,*) associated(electron%x),associated(proton%x), &
      & associated(hydrogen%core)!, associated(hydrogen%core%x)

  electron%x => cur_x(1)
  hydrogen%core => proton
  proton%x => cur_x(2)
  hydrogen%x => cur_x(3)
  cur_x(:) = 1.0
  write(*,*)electron%x,proton%x,hydrogen%x,hydrogen%core%x

end program test
于 2013-03-12T22:51:44.017 に答える
2
  1. が関連付けられていない場合は、最初のwriteステートメントでhydrogen%core参照(または定義)するのはプログラミングエラーです。hydrogen%core%xそのプログラミングエラーが存在する場合、それ以降は何でも起こります。

  2. 使用しているifortのバージョンはわかりませんが、ポリモーフィックポインターに関係するコンパイラーのバグがあります(Intelフォーラムの最近の投稿を思い出すと、現存していると思います)。

それはさておき、hydrogen%coreローカルproton変数を指すには、プロトンがTARGET属性を持っている必要があります。コンパイラがこれを診断することを期待します。

于 2013-03-12T22:52:48.203 に答える