【发布时间】:2017-02-09 15:37:57
【问题描述】:
我们最近发现我们正在对 Fortran 中的未分配数组进行赋值。 GNU gfortran 编译器没有发现错误,代码在 OSX 和 Linux 下都运行。但是,IBM Power PC 上出现相同的代码分段错误。
我的问题是,以下代码是否正确?似乎分配给array 的数组在某些架构上会自动分配内存,而在其他架构上则不会。这里有具体的实现细节吗?
代码是混合的 C/Fortran 代码:
#include <stdlib.h>
void assign_array_(double x[], int* n);
void print_array_();
int main()
{
int n,i;
double *x;
n = 5;
x = (double*) malloc(sizeof(double)*n);
for (i = 0; i < n; i++)
x[i] = (double) i;
assign_array_(x,&n);
print_array_();
return 0;
}
还有 Fortran 代码:
MODULE test_mod
DOUBLE PRECISION, ALLOCATABLE, DIMENSION(:) :: array
integer :: nsize
END MODULE test_mod
SUBROUTINE assign_array(x,n)
USE test_mod
IMPLICIT NONE
INTEGER :: n
DOUBLE PRECISION :: x(n)
CALL test_allocated()
array = x
CALL test_allocated()
nsize = n
END SUBROUTINE assign_array
SUBROUTINE print_array()
USE test_mod, ONLY: nsize, array
IMPLICIT NONE
INTEGER :: i
DO i = 1,nsize
WRITE(6,'(F24.16)') array(i)
END DO
END SUBROUTINE print_array
SUBROUTINE test_allocated()
USE test_mod
IMPLICIT NONE
IF (ALLOCATED(array)) THEN
WRITE(6,*) 'Array is allocated'
WRITE(6,*) 'size is ', SIZE(array)
ELSE
WRITE(6,*) 'Array is NOT allocated'
END IF
END SUBROUTINE test_allocated
输出(运行时)是:
Array is NOT allocated
Array is allocated
size is 5
0.0000000000000000
1.0000000000000000
2.0000000000000000
3.0000000000000000
4.0000000000000000
这是 Power PC 上的输出:
Array is NOT allocated
Segmentation fault (core dumped)
总结:它在 GNU (GNU Fortran (MacPorts gcc5 5.4.0_0) 5.4.0) gfortran on OSX (arch : x86_64h) 和 Linux(在 OSX、GNU Fortran (Ubuntu 4.9 .4-2ubuntu1~14.04.1) 4.9.4),但在使用 GNU Fortran (GCC) 4.4.7 20120313 (Red Hat 4.4.7-17) 编译的 Power PC (arch: ppc64) 上编译时无法运行。在我们的原始代码中,Power PC 实现只是在代码的更晚部分出现了段错误,其中引用了分配数组的条目,这使得我们的“错误”(如果它实际上是一个错误)真的很难追踪。
上述代码的正确行为是什么?
【问题讨论】:
-
你没有检查 malloc 是否成功。
-
我刚刚添加了一个检查,malloc 在所有情况下都成功。
-
如果数组没有分配,那么
array = x是非法的。 -
就是这样!在所有情况下,将
'fno-realloc-lhs添加到编译行都会触发 seg.fault。谢谢。 -
@stark 根据之前的评论(现在神秘消失了)GNU 4.6 及更高版本允许自动分配 LHS 数组。
标签: arrays memory fortran gfortran