Oop Fortran中指向指针的Class()指针:奇怪的行为
我已经仔细阅读了以前的文章,我不认为这个话题已经被讨论过了,希望有人能提供帮助。 我正在用fortran 2003编写代码,并使用ifort。我需要操纵以下类型,我设计了这些类型以提供所需的灵活性: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
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)保持为真
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
是编程错误。有了这个编程错误,一切都从那一点开始hydrogen%core
,质子必须具有TARGET属性。我希望编译器能够对此进行诊断
hydrogen%core
,则在第一个write语句中引用(或定义)hydrogen%core%x
是编程错误。有了这个编程错误,一切都从那一点开始hydrogen%core
,质子必须具有TARGET属性。我期待着通信