返回介绍

5.2.3 数组的动态分配

发布于 2025-03-08 16:28:35 字数 2478 浏览 0 评论 0 收藏 0

a) 可分配数组

数组可以是静态的也可以是动态的。如果数组是静态的,则在编译时就被分配了固定的储存空间,并且直到程序退出时才被释放。程序运行时静态数组的大小不能改变。静态数组的缺陷是,即使数组已经使用完毕,它仍占据着内存空间,浪费了系统资源。在给定的计算机内存资源情况下,耗费了其他数组可以利用的内存,并且超过资源的数组将导致程序执行错误。因此,F90 增加了动态的数组功能,动态数组的储存在程序运行当中是可以分配、改变和释放的。

动态数组只有两种:可分配数组和自动数组。自动数组和可分配数组很类似,区别在于当程序开始或结束时,自动数组会自动分配和释放内存。当用户分配动态存储空间时,数组的大小是在运行时而不是在编译时确定的。动态分配可以用于标量和任何类型的数组。当用户给数组指定了可分配属性时并没有立即分配内存,而是直到使用 ALLOCATE 语句后才分配。随后还可以用 DEALLOCATE 语句释放内存空间,这时数组可以以其它形状或目的来使用。

应该注意的是,WinNT/9x 上运行的 Visual Fortran 动态内存分配受一些因素的限制,包括交换文件的大小和其它同时运行的应用程序所需的内存大小。如果动态分配的内存太大或试图使用其它应用程序的保护内存会产生一般内存保护错误。碰到这类问题可以通过控制面板来改变虚拟内存的大小或交换文件的大小,还有一些编程技术可以降低内存需要。

b) ALLOCATE 语句

ALLOCATE 语句动态创建可分配数组,使内存和对象相联系。分配的对象可以被命名为任何有 ALLOCATABLE 属性的变量。它的一般形式为:

ALLOCATE(数组名[维界符][,数组名[(维界符[,维界符...])] ] ...[,STAT=状态值])。

例:REAL A(:),B(:,:,:)

ALLOCATABLE A,B

ALLOCATE(A(-2:40),B(3,3,3))

当数组被分配时,内存分配给指定大小的数组。ALLOCATE 语句中的秩必须和可分配数组的秩相同。在分配的同时,ALLOCATE 语句中的上下界决定了数组的大小和形状。边界的值可以是正数、负数或零,缺省的下界为 1。如果维上界比下界小,则该维的长度为零,并且数组的大小为零。大小为零的数组不能被赋值。

当前被分配的数组不能被再分配,否则会引起运行错误。错误状态可以由 ALLOCATE 语句中的 STAT 值获得。如果指定 STAT 选项,语句的成功执行时将返回 0,否则返回正值。若未指定 STAT 选项且出现错误时,程序将中止执行。

例:INTEGER, ALLOCATABLE :: A(:),B(:)

INTEGER ERR_MESSAGE

ALLOCATE(A(10:25),B(SIZE(A)),STAT=ERR_MESSAGE)

IF(ERR_MESSAGE.NE.0) PRINT *,'ALLOCATION ERROR'

可以用内在函数 ALLOCATED 来判断一个数组是否已被分配。它的形式为:ALLOCATED(数组名)。返回值是逻辑标量,已被分配时为真,现在还未被分配时为假,当数组的分配状态未定义时它也是未定义的。

例:REAL, ALLOCATABLE :: A(:)

...

IF(.NOT.ALLOCATED(A)) ALLOCATE(A(5))

c) DEALLOCATE 语句

DEALLOCATE 语句用来释放已分配数组的内存。它的一般形式为:DEALLOCATE(数组名[,数组名]...[,STAT=状态值])。

例:INTEGER, ALLOCATABLE :: A(:),B(:)

INTEGER ERR_MESSAGE

ALLOCATE(A(10:25),B(SIZE(A)))

DEALLOCATE(A,B,STAT=ERR_MESSAGE)

IF(ERR_MESSAGE.NE.0) PRINT *,'DEALLOCATION ERROR'

例:INTEGER,DIMENSION(:),ALLOCATABLE :: freq

READ *,limit

ALLOCATE(freq(1:limit))

DEALLOCATE(freq)

只有被 ALLOCATE 语句分配的内存空间才可以被 DEALLOCATE 语句释放,否则产生运行错误。可以使用 ALLOCATED 语句判断数组是否被分配,错误状态可以由 ALLOCATE 语句中的 STAT 值获得。

当过程的执行被 RETURN 或 END 语句中止时,除非可分配数组是有 SAVE 属性的,否则它的分配状态变成未定义的。但是,RETURN 和 END 语句并不释放数组分配的内存,所以应该在退出子程序前主动释放数组分配的内存。

可分配数组的联合状态可以是已分配的(该数组被 ALLOCATE 语句分配,可以被引用、定义或释放)或是目前未联合(该数组从未分配或上一个操作是释放,数组不能被引用或定义)。

当可分配数组赋值时就被定义。

例:INTEGER, ALLOCATABLE :: A(:)

ALLOCATE(A(100)) ! A 被分配但未定义,A 的分配状态是己分配

A(1:100)=1 ! A 被定义

DEALLOCATE(A) ! A 被释放,A 的分配状态是未分配

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文