在Fortran中动态分配字符串的问题

时间:2017-12-02 15:34:11

标签: fortran

我正在尝试使用可变长度字符串从NetCDF中读取一些数据。为了使用NetCDF调用,我必须提供足够大的字符串来容纳数据。但我遇到了问题。

我在gfortran编译器的奇怪行为中删除了问题。至少我认为是这样,但也许它是Fortran 90的功能。

以下是示例代码:

class MyList {
    public Node head();
} 

class Node {
    public int value() ;
    public Node next() ;
} 

我希望得到所有三个写语句“10 10 10”,因为我分配的字符串大小为10。

然而,这是我得到的:

    program test
    implicit none

    integer clen,slen
    character(len=:), allocatable :: string

    clen = 10
    allocate(character(len=clen) :: string)
    slen = len(string)

    write(6,*) 'clen,slen,dlen: ',clen,slen,len(string)
    string = ' '
    write(6,*) 'clen,slen,dlen: ',clen,slen,len(string)
    string = 'test'
    write(6,*) 'clen,slen,dlen: ',clen,slen,len(string)

    end

似乎每次分配字符串时都会重新分配字符串。这不是我期望的行为。

我可能使用过时的gfortran版本(GNU Fortran(Debian 4.9.2-10)4.9.2)。我的问题是:这种行为是否会随着编译器的新版本而消失,或者这是Fortran 90的一个特性?如果这是一个功能,我该如何避免呢?

1 个答案:

答案 0 :(得分:2)

  

似乎每次分配字符串时都会重新分配字符串。

情况确实如此。我首先要注意您的代码与Fortran 90兼容:Fortran 2003中引入了所谓的延迟长度字符变量。

当延迟长度字符变量是内在赋值的主题时(这是string=...所具有的),它采用右侧表达式的长度。这类似于behaviour with allocatable arrays

allocate语句string的长度为10,但是

string = ' '

右侧表达式的长度为1(单个空白)。这意味着string被释放,然后重新分配到这个新长度。

与数组类似,您可以使用子字符串保留赋值中左侧的长度:

string(:) = ' '

这样的子字符串不需要重新分配,您将看到固定长度字符串赋值的通常规则(填充或截断右侧)。

作为最终评论,这种重新分配是分配的情况。当您将string传递给填充字符串的NetCDF过程时,它不会进行此类重新分配:NetCDF过程会将伪参数视为不具有延迟长度。您的内在分配测试并不表示更广泛的行为。