Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pointers Fortran指针的深度副本_Pointers_Fortran_Fortran Iso C Binding - Fatal编程技术网

Pointers Fortran指针的深度副本

Pointers Fortran指针的深度副本,pointers,fortran,fortran-iso-c-binding,Pointers,Fortran,Fortran Iso C Binding,我想从c\u f\u pointer中保留一份生成的fortran指针的深度副本,以便进行检查等等 (编辑1:我使用“deepcopy”作为“制作独立于原件的副本” a = (/1,2,3,4/) a_deepcopy = a a_deepcopy(2) = 1 在上面的示例中,原始的a保持(/1,2,3,4/),而a\u deepcopy更改为(/1,1,3,4/)。如果它不是deepcopy,更改a_deepcopy的元素也会更改它原来的a的元素。我使用

我想从
c\u f\u pointer
中保留一份生成的fortran指针的深度副本,以便进行检查等等

(编辑1:我使用“deepcopy”作为“制作独立于原件的副本”

a             = (/1,2,3,4/)
a_deepcopy    = a
a_deepcopy(2) = 1   
在上面的示例中,原始的
a
保持
(/1,2,3,4/)
,而
a\u deepcopy
更改为
(/1,1,3,4/)
。如果它不是deepcopy,更改
a_deepcopy
的元素也会更改它原来的
a
的元素。我使用“deepcopy”一词只是因为我在Python上下文中见过这种命名。)

我在谷歌上搜索了很多fortran
指针
指向
可分配
数组的deepcopy示例,有人可能已经质疑过这个主题,但找不到合适的

以下将
指针
复制到
可分配
的代码编译并运行良好,以便在“可分配A2”数组中生成“指针p”的deepcopy,但根据我前面问题的答案,我知道我最好小心地以某种混合方式处理
指针
可分配
,即使它们似乎工作正常

program pointer3
implicit none
real*8,allocatable  :: A2(:)
real*8,target       :: A(4)
real*8,pointer      :: P(:)

A = 3.1416d0
P => A

allocate ( A2(size(A,1)) )
A2 = P         # Assign 'pointer' to 'allocatable'

print *, 'Initially'
write(*,'(a, 4f6.2)') 'A ', A
write(*,'(a, 4f6.2)') 'P ', P
write(*,'(a, 4f6.2)') 'A2', A2

P(2) = 1.d0

print *, 'After'
write(*,'(a, 4f6.2)') 'A ', A
write(*,'(a, 4f6.2)') 'P ', P
write(*,'(a, 4f6.2)') 'A2', A2

end program
问题是

  • 上述代码是否正确地将
    指针
    复制到
    可分配
    数组中

  • 如果我使用普通fortran
    指针
    及其
    目标
    ,我会尝试将其深度复制到
    可分配
    数组,只需将其
    目标
    属性分配到
    可分配
    ,如下所示(尽管我不能这样做,因为我使用的是
    c_f_指针
    ,而等效的
    目标
    c_ptr
    ,它不是fortran数组)

  • 第一次尝试将指针直接分配到可分配数组时,这很好,但这似乎很奇怪,因为显然“a”和“A2”的类型不同:
    real*8,allocatable
    real*8,target

    我认为上面两种制作fortran
    指针
    深度复制的方法都不合适,也不安全。我如何才能以安全可靠的方式制作
    指针
    的深度复制


    感谢您阅读此问题。

    开头有一句警告:指针可能有用,但也非常危险,因为很容易产生非常模糊且难以调试的错误

    我不记得有那么多的案例,我真诚地想:是的,这里的指针是个好主意(尽管有一些)

    让我们从讨论数组开始:普通数组必须在编译时声明其形状,如下所示:

    INTEGER :: A(10)
    
    这导致程序在内存中留出一个区域来存储十个整数值

    但您并不总是知道在编码时数组实际必须有多大。这就是Fortran引入可分配数组的原因。代码不是在开始时声明它们的形状,而是告诉编译器应该准备好以后需要内存

    INTEGER, ALLOCATABLE :: A(:)
    
    这告诉编译器它需要一个整数数组,但它还不知道它有多大。然后,当程序运行并计算出它需要多大的数组时,您可以使用
    ALLOCATE
    命令实际创建内存:

    ALLOCATE(A(100))
    
    只有在对数组调用了
    ALLOCATE
    之后,才能真正使用它。(实际上,使用可分配数组还有更多的原因,但我现在还不详细介绍。)

    指针是不同的。指针不存储值,而是存储值所在的内存地址。因此,在实际与值交互之前,首先需要执行以下两项操作之一:

  • 将指针指向目标,例如:

    P => A
    
  • 分配指针指向的内存:

    ALLOCATE(P)
    
    您可以看到,它也使用了
    ALLOCATE
    命令,但使用方式略有不同:当您分配一个可分配数组时,您将直接分配的内存与该数组相关联。当您分配一个指针时,您分配内存,然后将该内存的地址写入与指针关联的内存中

  • 话虽如此,让我们来看看你在做什么:

    A
    或多或少是一个普通数组,除了关键字
    target
    告诉编译器应该可以让指针指向该数组之外。 将此数组的所有元素设置为一个值

    p
    是指向数组的指针。您将
    p
    指向
    a
    ,这意味着这两个指针现在在完全相同的内存上工作。更改一个,另一个也会更改

    然后为
    A2
    分配内存
    A2
    就像任何其他数组一样,它与
    A
    p
    无关

    因为
    p
    A
    引用相同的内存,所以这两行具有相同的效果:

    A2 = A
    A2 = P
    
    在这两种情况下,数组
    A
    的内容都会复制到
    A2
    的内存中。然后,更改
    A
    中的任何值(无论您是使用
    A
    还是
    p
    来执行此操作都无关紧要)也将在
    P
    中显示为更改。但是
    A2
    的值不会更改:它们存储在其他地方

    用指针思考真的很难。当我真的必须这样做时,我通常会事先在一张纸上画出过程,这样我就可以跟踪哪个指针在什么时候指向哪里


    在Fortran中,您通常不需要指针。没有指针,每个副本都是您所说的“深度副本”。

    请不要使用非标准、不可移植的real*8,它不是Fortran的一部分,也从来不是Fortran的一部分。请看。在您的问题中,您能否定义“深度副本”的含义-我不认为你没有用它
    P => A
    
    ALLOCATE(P)
    
    A2 = A
    A2 = P