专栏首页量子化学Fortran中的陷阱——可分配数组的size

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

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

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

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

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。编译程序并运行,输出如下所示:

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()查询,否则得到的数组的大小可能是这个数组上一次被分配的大小。

本文分享自微信公众号 - 量子化学(quantumchemistry),作者:zxli

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-12-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Dalton使用——磷光及其相关过程

    注册验证:它用的是一些计算化学方法填空的方式进行验证的。coupled后面cluster;configuration后面填interaction;Møller后...

    用户7592569
  • 第一激发三重态的几何结构优化

    在单三态能量差ΔEST以及磷光的计算中都会涉及第一激发三重态T1的几何结构优化。本文单独谈一下T1的结构优化。T1的结构优化常用以下两种方式:(1)将自旋多重度...

    用户7592569
  • 从ORCA中获取Gaussian格式的重收缩def2系列基组文件

    该基组用途请阅读卢天老师博文《使用Gaussian做镧系金属配合物的量子化学计算》,链接:

    用户7592569
  • C++核心准则Enum.8:只在必要时指定枚举值

    Enum.8: Specify enumerator values only when necessary

    面向对象思考
  • 【python游戏编程之旅】第七篇---pygame中的冲突检测技术

    本系列博客介绍以python+pygame库进行小游戏的开发。有写的不对之处还望各位海涵。

    马三小伙儿
  • 【React】377- 实现 React 中的状态自动保存

    移动端中,用户访问了一个列表页,上拉浏览列表页的过程中,随着滚动高度逐渐增加,数据也将采用触底分页加载的形式逐步增加,列表页浏览到某个位置,用户看到了感兴趣的项...

    pingan8787
  • 语音识别系统的分类、基本构成与常用训练方法 | Machine Speech

    对于想进入语音识别领域的学习者来说,了解语音识别系统的一些基本概念,会有助于更快的进入这个行业的交流平台,本文对语音识别系统的一些常见概念做了整理,希望能对刚...

    用户7623498
  • hippy-react 支持转小程序

    思考:我们技术栈hippy-react,其他业务也有同构小程序的需求,是否可以支持项目一键转小程序,减少重复开发;

    melodyren
  • pyhanlp 中文词性标注与分词简介

    pyhanlp实现的分词器有很多,同时pyhanlp获取hanlp中分词器也有两种方式

    IT小白龙
  • FFmpeg使用手册 - FFmpeg 的编译安装

    FFMpeg在官方网站中提供了已经编译好的可执行文件,用FFmpeg的人很多,因为FFmpeg是开源的,并且可以自己DIY,而且很强大,所以,FF...

    用户3765803

扫码关注云+社区

领取腾讯云代金券