【发布时间】:2022-01-31 08:14:16
【问题描述】:
以下代码可在 GNU gfortran 和 Intel ifort 中编译。但是只有gfortran编译的版本才能成功运行。
program fort_tst
use iso_c_binding
INTEGER, POINTER :: a(:)
TYPE(C_PTR) :: ptr
INTEGER, POINTER :: b(:)
ALLOCATE(a(5))
ptr = c_loc(a)
CALL c_f_pointer(ptr,b,[5])
DEALLOCATE(b)
end program fort_tst
Intel编译代码中的错误是:
forrtl: severe (173): A pointer passed to DEALLOCATE points to an object that cannot be deallocated
Image PC Routine Line Source
fort_tst 000000000040C5A1 Unknown Unknown Unknown
fort_tst 0000000000403A17 Unknown Unknown Unknown
fort_tst 0000000000403812 Unknown Unknown Unknown
libc-2.17.so 00002AAAAB20F555 __libc_start_main Unknown Unknown
fort_tst 0000000000403729 Unknown Unknown Unknown
gfortran 代码运行完成。快速 valgrind 检查没有发现任何泄漏。
有人可以确认上面的代码是否有效/合法代码吗?
我在跑步
ifort (IFORT) 2021.2.0 20210228
和
GNU Fortran (GCC) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
更新:
有趣的是 gfortran 做了正确的事(即只释放分配的内存),即使用户试图用不正确的索引重新映射或虚假的形状参数来混淆它。所以内部数组描述符正在被 gfortran 的 c_f_pointer 正确复制。
【问题讨论】:
-
请更新我对您的 UPDATE 的回答。
-
gfortran 模仿 C malloc/free 行为是有道理的。我想我只是没有意识到它是如此明确。我认为 gfortran 是“本机”fortran 编译器?
-
它是一个原生编译器。但是所有这些编译器通常都在后台使用系统内存分配器。在 Linux 中,最常见的是来自 GLIBC(GNU C 库)的
malloc()/free()对,但也可以使用其他一些实现,甚至是自定义分配器。这意味着allocate在后台调用malloc而deallocate在后台调用free。但不仅如此,它还填写各种描述符数据字段。这对我知道的所有编译器都很常见,包括英特尔。 -
这类似于
new和delete在 C++ 中所做的,它们也最常调用malloc和free。
标签: pointers fortran gfortran intel-fortran fortran-iso-c-binding