我在任何地方都找不到这个,即使它可能微不足道,我想确保我已经很好地理解了。我有 4 个问题(严格相关):
1)如果我像这样在 fortran 中定义派生类型
TYPE :: node
INTEGER :: int
REAL :: REALfirst
REAL :: REALsecond
END TYPE
TYPE(node) :: var
allocate(var)
经过上述分配后,它占用 4 个字节用于整数,另外 8 个字节用于 2 个单精度实数,总共 12 个字节。它们是否连续位于内存中?计算机如何存储有关变量类型的信息?我猜它需要一些额外的内存来保存它。
2)上面例子中的if代替
TYPE(node) :: var
我会写:
TYPE(node),POINTER :: var
我猜如果我编译了一个 32 位可执行文件,ALLOCATE 语句将分配与上面示例中相同的内存量。正确吗?
3)现在假设我声明类型
TYPE :: node
INTEGER :: int
TYPE(node), POINTER :: BEFORE
TYPE(node), POINTER :: AFTER
END TYPE
TYPE(node) :: var
allocate(var)
这里(如果是 32 位编译的)它将为整数分配 4 个字节,为 2 个指针分配 8 个字节,总共 12 个字节。这是正确的吗?计算机如何存储有关变量类型的信息?
4)在例子(3)中,如果我现在写ALLOCATE(var%BEFORE),其他12个字节被分配给派生类型节点的变量,4个字节的整数类型被分配给指针var%之前(参见示例 3)现在已被释放,对吗?
谢谢 答:
最佳答案
1) Fortran 标准未涵盖这一点。 real
和 integer
不必是 4 个字节宽。通过指定它们的精度来确保。如果您不关心数字精度,而是关心字节数,请这样做
!In Fortran 2008
use iso_fortran_env
or
!In Fortran 95
integer,parameter :: int32 = selected_int_kind(9)
integer,parameter :: real32 = selected_real_kind(p=6,r=37)
and
TYPE :: node
INTEGER(int32) :: int
REAL(real32) :: REALfirst
REAL(real32) :: REALsecond
END TYPE
编译器可以插入任何它想要的填充。如果您将 4 个、8 个甚至更多字节的变量混合在一起,则可能会发生这种情况。要抑制任何填充,请使用 SEQUENCE
。
2) 分配的内存将是相同的。编译器还使用一些数据结构(可能只是一个地址,但不是必须的)进行簿记。
3)我提到的簿记数据结构存储在数据类型中。它可能只是一个地址。
4) 指针数据结构可以是4个字节,也可以更多。然而,更重要的一点是,他们没有被释放。您必须知道在堆上哪里可以找到分配的空间,并为此使用指针。无论您使用此指针分配新数据,还是指向某个现有数据,都没有关系。
请注意,派生类型的位大小在运行时不能更改,它是固定的。另一个问题是多态变量,但因此必须动态分配它们。
关于pointers - 派生类型(在 Fortran 中)占用多少字节?这些地点是连续的吗?以及指向派生类型的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14205294/