Oop Fortran中指向指针的Class()指针:奇怪的行为

Oop Fortran中指向指针的Class()指针:奇怪的行为,oop,pointers,fortran,derived-types,Oop,Pointers,Fortran,Derived Types,我已经仔细阅读了以前的文章,我不认为这个话题已经被讨论过了,希望有人能提供帮助。 我正在用fortran 2003编写代码,并使用ifort。我需要操纵以下类型,我设计了这些类型以提供所需的灵活性: module parameters double precision, target :: cur_x(3) type fundamental double precision, pointer :: x => null() e

我已经仔细阅读了以前的文章,我不认为这个话题已经被讨论过了,希望有人能提供帮助。 我正在用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>
导致分割错误。表演

hydrogen%core%x => null()
允许代码运行,但关联的(氢%core%x)保持为真

  • 我已确保将父指针列表与子指针列表相关联,如中所建议的。质子%x在工作,但氢%x核产生垃圾这一事实我不明白
  • 我可以解决这个问题,但这将牺牲我在更复杂的计算中需要的通用性。我也很想了解这里出了什么问题

    谢谢你的帮助! 吉姆

    编辑:为各种事物添加“目标”属性;请注意,这些都在代码中,我只是在转到这篇文章时忘记了它们


    EDIT:澄清一下,我对上述代码的主要问题是,最终写入命令为%core%x提供了未初始化的输出,即使在第一次写入后遵循关联命令也是如此。尽管我在类型定义中将core初始化为null,但它似乎有问题;如果我尝试在代码顶部将其置零,程序就会崩溃。

    基本问题是
    氢%核心
    没有关联。因此,
    相关(氢%芯%x)
    的影响是不确定的。如果派生类型指针(
    hydrogen%core
    )的字段(
    x
    )没有关联,例如指向
    null()
    ,而不是内存中现有的派生类型实例,则无法访问/查询该字段。您的编译器可能会生成一个代码,当您尝试它时,它不会立即崩溃,但之后所做的任何事情都是不确定的,因为您可能已经覆盖了随机内存地址中的一些数据

    事实上,我用各种编译器编译了一个代码的自包含版本(见下文),在第一个write语句中,我立即得到了SEGFULTS。使用适当的检查选项,其中一个二进制文件甚至会在引用已解除关联的指针时报告原因。如果注释掉有问题的
    associated()
    查询(如下代码所示),所有二进制文件都可以正常运行

    另外,请注意,变量
    electron
    proton
    必须具有target属性,否则代码甚至不应该编译。如果您的编译器编译代码时没有抱怨,那么您可能应该考虑更改为其他编译器

      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
    

    基本问题是,
    氢%堆芯
    没有关联。因此,
    相关(氢%芯%x)
    的影响是不确定的。如果派生类型指针(
    hydrogen%core
    )的字段(
    x
    )没有关联,例如指向
    null()
    ,而不是内存中现有的派生类型实例,则无法访问/查询该字段。您的编译器可能会生成一个代码,当您尝试它时,它不会立即崩溃,但之后所做的任何事情都是不确定的,因为您可能已经覆盖了随机内存地址中的一些数据

    事实上,我用各种编译器编译了一个代码的自包含版本(见下文),在第一个write语句中,我立即得到了SEGFULTS。使用适当的检查选项,其中一个二进制文件甚至会在引用已解除关联的指针时报告原因。如果注释掉有问题的
    associated()
    查询(如下代码所示),所有二进制文件都可以正常运行

    另外,请注意,变量
    electron
    proton
    必须具有target属性,否则代码甚至不应该编译。如果您的编译器编译代码时没有抱怨,那么您可能应该考虑更改为其他编译器

      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
    
  • 如果未关联
    hydrogen%core
    ,则在第一个write语句中引用(或定义)
    hydrogen%core%x
    是编程错误。有了这个编程错误,一切都从那一点开始

  • 你没有说你使用的是什么版本的ifort,但是已经有(如果我记得最近在英特尔论坛上发表的文章,我认为是现存的)编译器错误与多态指针有关

  • 除此之外,对于要指向本地质子变量的
    hydrogen%core
    ,质子必须具有TARGET属性。我希望编译器能够对此进行诊断

  • 如果未关联
    hydrogen%core
    ,则在第一个write语句中引用(或定义)
    hydrogen%core%x
    是编程错误。有了这个编程错误,一切都从那一点开始

  • 你没有说你使用的是什么版本的ifort,但是已经有(如果我记得最近在英特尔论坛上发表的文章,我认为是现存的)编译器错误与多态指针有关

  • 除此之外,对于要指向本地质子变量的
    hydrogen%core
    ,质子必须具有TARGET属性。我期待着通信