前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Fortran中的陷阱——可分配数组的size

Fortran中的陷阱——可分配数组的size

作者头像
用户7592569
发布2021-01-04 14:53:22
2.6K0
发布2021-01-04 14:53:22
举报
文章被收录于专栏:量子化学量子化学

早期的Fortran程序多使用静态数组。在编译时,静态数组被分配固定的存储空间,且在程序运行过程中静态数组的大小是不会改变的。为了能够存储足够多的数据,静态数组的大小需要足够大,这会造成内存的浪费。如果静态数组的大小不够大,程序的运行也可能会出现错误。

在Fortran90标准之后,我们可以很方便地使用可分配数组。使用allocatable属性定义可分配数组,allocate和deallocate语句动态地为数组分配和释放内存。使用size语句可以查询可分配数组的大小(元素总数)。

若一个可分配数组的内存已经被释放了,数组内元素的总数是0。然而,笔者最近发现,仍然用size语句查询其大小,得到的结果却是上一次其被分配的大小。 以下面的测试程序为例:

代码语言:javascript
复制
program size_test
    implicit none
    integer,allocatable :: values(:)
    call modify_size(5)
    call modify_size(0)
contains
subroutine modify_size(n)
    implicit none
    integer :: n
    integer :: i
    if (allocated(values)) deallocate(values)
    if (n>0) then
        allocate(values(n))
        values = 1
    end if
    write(*,"(A,I0)") "size ofvalues = ",size(values)
    do i=1,size(values)
        write(*,"(A,I0,A,I0)")"values(",i,") = ",values(i)
    end do
end subroutine modify_size
end program size_test

其中,values作为可分配数组。子程序modify_size通过输入参数n来给values分配内存,若n>0则将values的大小设置为n并赋值values为1,否则不给values分配内存。随后输出values的大小和所有元素的值。主程序中先取modify_size的输入参数为5,再取0。编译程序并运行,输出如下所示:

代码语言:javascript
复制
size of values = 5
values(1) = 1
values(2) = 1
values(3) = 1
values(4) = 1
values(5) = 1
size of values = 5
forrtl: severe (174): SIGSEGV, segmentation faultoccurred
Image              PC                Routine            Line        Source            
size_test          000000000040400D  Unknown               Unknown  Unknown
libpthread-2.17.s  00002B004C5575E0  Unknown               Unknown  Unknown
size_test          0000000000403150  Unknown               Unknown  Unknown
size_test          0000000000402C1E  Unknown               Unknown  Unknown
libc-2.17.so       00002B004C785C05  __libc_start_main     Unknown  Unknown
size_test          0000000000402B29  Unknown               Unknown  Unknown

第一轮输出完全正确,values的大小被设置成了5,并且数组中的元素全是1。然而第二次调用modify_size时,释放values的内存后没有分配values的大小,size(values)的值还是5。在输出values的值时程序会报错。

这个例子说明当使用可分配数组时,查询可分配数组的大小前需要先查询其是否被分配了内存,即用allocated()查询,否则得到的数组的大小可能是这个数组上一次被分配的大小。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 量子化学 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档