我需要从fortran中的子例程返回一个字符串数组,其长度应该在运行时确定 . 我找到的解决方案,与英特尔Fortran一起工作,然而与gfortran崩溃 .
示例代码
以下代码似乎适用于英特尔Fortran(15.0.3),但因gfortran 5.3.0的分段错误而失败:
program stringtest ! filename:str2.f08
implicit none
integer n
character(len=:), allocatable :: y(:)
write(*,*) 'mkchars...'
call mkchars(y)
write(*,*) 'mkchars... Done.'
write(*,'(5("|",A,"|"))') y
contains
subroutine mkchars(oc)
character(len=:), allocatable, intent(out) :: oc(:)
allocate(character(len=8) :: oc(5))
write(*,*) 'shape ', shape(oc)
write(*,*) 'length ', (len(oc(n)), n=1,5)
write(*,*) 'storage', storage_size(oc)
oc(1) = "Hello"
oc(2) = "World" ! <-------------------- crashes here with gfortran
oc(3) = "how"
oc(4) = "are"
oc(5) = "you?"
end subroutine mkchars
end program stringtest
IFort输出
使用英特尔Fortran 15.0.3,可以生成
mkchars...
shape 5
length 8 8 8 8 8
storage 64
mkchars... Done.
|Hello ||World ||how ||are ||you? |
GFortran:可执行文件在分配给OC时崩溃(2)
但是,使用gfortran时,在分配给 OC(2)
时会出现分段错误,即使数组的形状和每个条目的长度按预期报告:
C:\tmp>gdb -batch -ex run -ex bt a.exe
[New Thread 12024.0x38e4]
mkchars...
shape 5
length 8 8 8 8 8
storage 64
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401840 in mkchars (oc=<incomplete type>, _oc=_oc@entry=0x61fdbc) at c:/tmp/str2.f08:20
20 oc(2) = "World"
#0 0x0000000000401840 in mkchars (oc=<incomplete type>, _oc=_oc@entry=0x61fdbc) at c:/tmp/str2.f08:20
#1 0x00000000004019a0 in stringtest () at c:/tmp/str2.f08:9
#2 0x0000000000401a84 in main (argc=1, argv=0x6f5890) at c:/tmp/str2.f08:9
#3 0x00000000004013e8 in __tmainCRTStartup ()
#4 0x000000000040151b in mainCRTStartup ()
我做错了什么,或者这是一个可能的编译错误?
是否有一些其他方法从子程序返回分配的字符串数组在gfortran中工作?
对于手头的实际用例,我可以回到使用超大的固定大小的阵列(大约100KB而不是<1KB)并忽略未使用的部分 . 但我更喜欢更清洁的解决方案 .
1 回答
我一段时间为我的代码“MOONS”编写了一个Fortran字符串类 . 我编写字符串类的方法是首先在派生类型(char)中包装单个字符,然后创建一个使用char类型的可分配的外部类(字符串) . 这样,我避免编写可分配的字符,而是编写一个可分配的派生类型 .
当我第一次开发这个类时,我首先尝试使用您所显示的相同方法,但我遇到了编译/运行时错误 . 此字符串类适用于gfortran 4.9.2 . 我已经测试了其他版本,但我不记得具体哪些版本 .
这是github,它将拥有最新的字符串类版本
https://github.com/charliekawczynski/MOONS
字符串类的当前目录是
https://github.com/charliekawczynski/MOONS/blob/master/code/pre_generated/string.f90
但我不能保证将来不会改变 . 我会在这里包含当前版本: