我的代码很复杂,但下面的MWE Fortran程序显示了该问题,并导致了英特尔Fortran 18.0.5中的分段错误。
forrtl: severe (174): SIGSEGV, segmentation fault occurred回溯显示在NN= malloc(nsize)上调用malloc()时出现问题
对于gfortran,它还会导致以下错误
./a.out: free(): invalid next size (fast): 0x0000000000603b40 ***源码是:
program test
c this program tests memory allocation
read(*,*)k
call test_cray(k)
end
subroutine test_cray(k)
#ifdef BIT64
integer*8 NN, nsize
#endif
real x(*)
real*8 prob(k,k, 128, 128)
real*8 prob1(k,k, 128, 128)
real*8 prob2(k,k, 128, 128)
pointer(NN , x)
nsize = k*4*128*128
nsize =20
NN= malloc(nsize)
do i =1, 20
x(i)=0.1*(i-1)
end do
NN =loc(x)
write(*,*) NN
!write(*,*) "shape of x=", shape(x)
call shape_cray(NN)
write(*,*)"shape_cray returned"
end
subroutine shape_cray(NN )
real y
pointer(nx , y)
do i =1, 20
nx = NN + (i-1)*4
write(*,*)nx, y
end do
write(*,*) NN
write(*,*) "shape of y=", shape(y)
write(*,*) "y=", y
end请注意,程序中的空格必须针对降价进行调整。在没有分段错误的情况下,正确的方法是什么?
下面是输出:
prompt> ifort -g -O0 -traceback -DBIT64 -mcmodel=large cray_test1.F
prompt> ./a.out
128
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
libifcoremt.so.5 00007F70F617F49C for__signal_handl Unknown Unknown
libpthread-2.12.s 00000034A2C0F790 Unknown Unknown Unknown
a.out 0000000000400C3B test_cray_ 19 cray_test1.F
a.out 000000000040097D MAIN__ 5 cray_test1.F
a.out 00000000004008CE Unknown Unknown Unknown
libc-2.12.so 00000034A241ED5D __libc_start_main Unknown Unknown
a.out 00000000004007D9 Unknown Unknown Unknown我使用了k=120。
发布于 2020-03-15 01:01:07
正确的答案是“不要使用Cray指针,使用可分配的实体”。但考虑到有人可能正在使用和更新遗留代码。这修复了您的示例并使代码现代化。注意,我没有使用contains子程序,也没有提供接口语句。所以,你仍然有隐式的接口。
program test
implicit none
integer k
read(*,*) k
if (k > 0) call test_cray(k)
end
subroutine test_cray(k)
use iso_c_binding, only : c_intptr_t
implicit none
integer, intent(in) :: k
integer(c_intptr_t) nn
integer i, nsize
real x(*)
pointer(nn, x)
nsize = k
nn = malloc(nsize)
x(1:nsize) = 0.1 * [(i - 1, i = 1, nsize)]
nn = loc(x)
write(*,*) nn
call shape_cray(nn, nsize)
end subroutine test_cray
subroutine shape_cray(nn, nsize)
use iso_c_binding, only : c_intptr_t
implicit none
integer(c_intptr_t), intent(in) :: nn
integer, intent(in) :: nsize
real y
integer i
pointer(nx, y)
do i = 1, nsize
nx = nn + (i - 1) * 4 ! Assumes REAL is 4 bytes.
write(*,*) nx, y
end do
write(*,*) nn
write(*,*) "shape of y = ", shape(y)
write(*,*) "y = ", y
end subroutine shape_cray对于gfortran,这给出了
gfcx -o z -fcray-pointer a.f
./z
2
671645728
671645728 0.00000000
671645732 0.100000001
671645728
shape of y =
y = 0.100000001 https://stackoverflow.com/questions/60673252
复制相似问题