Pointers 用于malloc的非第一个元素的Cray指针

Pointers 用于malloc的非第一个元素的Cray指针,pointers,fortran,fortran77,cray-pointers,Pointers,Fortran,Fortran77,Cray Pointers,我正在尝试更新一些用Fortran 77编写的旧代码。最终,我的目标是使其符合F90+标准,但目前我仍在努力理解其中的一些细节 我已经添加了implicit none并明确指定了每个变量,删除了90%的goto语句,使循环更干净,并重新组织了许多其他内容。我目前的问题是,我不完全理解cray指针是如何用来分配内存的。例如,我看到如下情况: integer :: nx1, nz integer :: x1, z pointer ( ptr_x1, x1(1) ) pointer ( ptr_

我正在尝试更新一些用Fortran 77编写的旧代码。最终,我的目标是使其符合F90+标准,但目前我仍在努力理解其中的一些细节

我已经添加了
implicit none
并明确指定了每个变量,删除了90%的
goto
语句,使循环更干净,并重新组织了许多其他内容。我目前的问题是,我不完全理解cray指针是如何用来分配内存的。例如,我看到如下情况:

integer :: nx1, nz
integer :: x1,  z
pointer ( ptr_x1, x1(1)   )
pointer ( ptr_z,  z(1000) )

...

ptr_x1 = proprietary_malloc(nx1*SIZEOF_INTEGER)
ptr_z  = proprietary_malloc(nz *SIZEOF_INTEGER)

...

proprietary_free(ptr_x1)
proprietary_free(ptr_z)
注意,
privative\u malloc
应该是
c
malloc
的包装,带有一些基本的内部内存检查。我非常确信代码应该在退出之前调用
free
(原始的F77代码根本不…yikes),因此我将自己添加到上面的示例中

如果我理解正确,在第一个
malloc
语句之后,
x1
可以用作
nx1
整数的数组。但是第二句话之后的
z
呢?有人能给我解释清楚这是如何动态分配内存的吗?我更习惯于
分配
c++
新的
语句


我正在使用
ifort
进行编译,以防您需要这些信息。谢谢你的帮助。

[简短回答]我认为
z
可以用作
nz
整数的数组,如果我们忠实地翻译原始代码,就可以将它们分配为

integer, allocatable :: x1(:), z(:)
allocate( x1( nx1 ), z( nz ) )
因为原始代码中
z
的索引可能会运行到1000,所以确保
nz>=1000
可能更安全

[长答案]根据这些页面(,),类似
指针(ptr,a(n1,n2,…)
的声明告诉编译器从
ptr
开始作为
a(1:n1,1:n2,…)
访问内存;i、 例如,
n1
n2
。。。表示数组维度,而不是起始索引。在下面的示例中,所有
a(1)
b(1)
c(1)
d(1)
都映射到
池(3)

因此给出(使用
gfortran-fcray指针

实际上,Cray指针的关联规则似乎与伪参数的关联规则非常相似,例如:

program main
    implicit none
    integer pool( 5 )

    pool = [ 1, 2, 3, 4, 5 ]

    call sub( pool(3), pool(3), pool(3), pool(3) )
end

subroutine sub( a, b, c, d )
    implicit none
    integer a( 5 ), b( 10 ), c( * ), d( 1 )

    print *, "a: ", a( 1:5 )
    print *, "b: ", b( 1:5 )
    print *, "c: ", c( 1:5 )
    print *, "d: ", d( 1:5 )
end
这给出了相同的结果。我们注意到,所有
a
b
c
d
访问物理分配的内存(池(1:5))之外的内存,因此显示了最后两个元素的垃圾数据。另外,
print*,d(1:5)
违反了声明的大小
d(1)
,可以使用
gfortran-fcheck=all…
等选项进行检查


现在回到OP的程序,
ptr_x1
ptr_z
是从malloc-like例程(对于
nx1
nz
整数)获得的物理地址,所以我想用这些大小分配
x1
z
可能是可以的,只要
nx1
nz
给出了正确的值。

这不是Fortran 77的问题,Cray指针从来都不是标准的。感谢您的有趣讨论。我已经确认了你的测试,它们似乎与我的结果相符。此外,我办公室的某个人能够解释编写
指针(ptr_z,z(1000))
背后的原因。显然,这与我们在90年代使用的老式调试器有关。通过在那里写入1000,它告诉调试器前1000个元素应该在堆栈上(因此调试器可以访问),而不是在堆上。现在,这完全不相关,所以是的,我应该能够将其重写为
allocate(z(nz))
,并且仍然能够使用任何编译器访问信息。
a:            3           4           5           0   275788968
b:            3           4           5           0   275788968
c:            3           4           5           0   275788968
d:            3           4           5           0   275788968
program main
    implicit none
    integer pool( 5 )

    pool = [ 1, 2, 3, 4, 5 ]

    call sub( pool(3), pool(3), pool(3), pool(3) )
end

subroutine sub( a, b, c, d )
    implicit none
    integer a( 5 ), b( 10 ), c( * ), d( 1 )

    print *, "a: ", a( 1:5 )
    print *, "b: ", b( 1:5 )
    print *, "c: ", c( 1:5 )
    print *, "d: ", d( 1:5 )
end