【问题标题】:Segmentation fault - invalid memory reference problem in fortran分段错误 - fortran 中的无效内存引用问题
【发布时间】:2020-02-04 07:58:41
【问题描述】:

我正在尝试使用 fortran 从数据中计算值。

program signifikansi
implicit none
integer :: N_energi, N_sudut, i, N
double precision,allocatable :: theta1(:), theta_lab1(:), dsig1(:), dsig_lab1(:), pol1(:), dpolxx1(:), dpolxz1(:), phase1(:), t1(:)
double precision,allocatable :: theta2(:), theta_lab2(:), dsig2(:), dsig_lab2(:), pol2(:), dpolxx2(:), dpolxz2(:), phase2(:), t2(:)   
double precision,allocatable :: signif(:) 
double precision :: signif_total,signif2

    write(*,*)"Masukkan jumlah energi"
    read(*,*)N_energi

    write(*,*)"Masukkan jumlah sudut pada setiap energi"
    read(*,*)N_sudut

N=N_sudut*N_energi

    write(*,*)"Total data adalah",N

open(unit=10, file='kminpobs.dat', status="old", action="read")
allocate(theta1(N))
allocate(theta_lab1(N))
allocate(dsig1(N))
allocate(dsig_lab1(N))
allocate(pol1(N))
allocate(dpolxx1(N))
allocate(dpolxz1(N))
allocate(phase1(N))
allocate(t1(N))

do i=1,N
read(10,*) theta1(i), theta_lab1(i), dsig1(i), dsig_lab1(i), pol1(i), dpolxx1(i), dpolxz1(i), phase1(i), t1(i)
end do
close(10)

open(unit=10, file='kminpnoscalar.dat', status="old", action="read")
allocate(theta2(N))
allocate(theta_lab2(N))
allocate(dsig2(N))
allocate(dsig_lab2(N))
allocate(pol2(N))
allocate(dpolxx2(N))
allocate(dpolxz2(N))
allocate(phase2(N))
allocate(t2(N))

do i=1,N
read(10,*) theta2(i), theta_lab2(i), dsig2(i), dsig_lab2(i), pol2(i), dpolxx2(i), dpolxz2(i), phase2(i), t2(i)
end do
close(10)

do i=1,N
signif(i) = (ABS(dsig2(i)-dsig1(i)))/dsig1(i)
end do

signif_total = SUM(signif)

signif2 = signif_total/N

write(*,*)"Hasil signifikansi untuk partikel tersebut adalah",signif2

deallocate(theta1)
deallocate(theta_lab1)
deallocate(dsig1)
deallocate(dsig_lab1)
deallocate(pol1)
deallocate(dpolxx1)
deallocate(dpolxz1)
deallocate(phase1)
deallocate(t1)
deallocate(theta2)
deallocate(theta_lab2)
deallocate(dsig2)
deallocate(dsig_lab2)
deallocate(pol2)
deallocate(dpolxx2)
deallocate(dpolxz2)
deallocate(phase2)
deallocate(t2)

end program signifikansi

这是我的代码,但我得到的只是这样的错误消息

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x7F0C2BFC2777
#1  0x7F0C2BFC2D7E
#2  0x7F0C2BC1AD3F
#3  0x403034 in MAIN__ at signifikansi1.f90:?
Segmentation fault

输入的 N_energi 为 39,N_sudut 为 120。 我在输出中得到了 N 值,但我的代码无法计算进一步的结果。

谁能帮我解决这个问题?谢谢你。 我的猜测是我使用的数组大小太大。

【问题讨论】:

  • 欢迎您,请拨打tour 并阅读How to Ask。对于所有 Fortran 问题,也请使用标签 fortran。无论何时调试,都应该使用 gfortran 中的错误检查和调试标志。使用gfortran -g -Wall -fcheck=all,您将获得更好的信息,也为我们提供。请注意,如果没有您的输入文件,我们将无法测试您的程序。请使用我提到的标志重新编译您的程序,并使用edit 更新错误消息。如果可能,请向我们展示输入文件。
  • 你还没有分配signif。可能还有其他错误,但没有输入文件,因为 VladimirF 说我们无法测试它

标签: segmentation-fault fortran gfortran


【解决方案1】:

我已使用免费的 GNU Fortran 将您的代码加载到我的 Eclipse IDE 中。

我已经运行了 Project - Build All。它编译代码的方式是使用标志 -WAll 来显示所有警告,这总是一个好主意。您的 Fortran 编译器可能有一组不同的标志可供选择。



13:26:49 **** Build of configuration Debug for project TestFortran2 ****
make all 
Building file: ../TestFortran2.f90
Invoking: GNU Fortran Compiler
gfortran -funderscoring -O0 -g -Wall -c -fmessage-length=0 -o "TestFortran2.o" "../TestFortran2.f90"
../TestFortran2.f90:52:0:

 signif(i) = (ABS(dsig2(i)-dsig1(i)))/dsig1(i)

Warning: 'signif.offset' may be used uninitialized in this function [-Wmaybe-uninitialized]
../TestFortran2.f90:55:0:

 signif_total = SUM(signif)

Warning: 'signif.offset' may be used uninitialized in this function [-Wmaybe-uninitialized]
../TestFortran2.f90:55:0: Warning: 'signif.dim[0].lbound' may be used uninitialized in this function [-Wmaybe-uninitialized]
../TestFortran2.f90:55:0: Warning: 'signif.dim[0].ubound' may be used uninitialized in this function [-Wmaybe-uninitialized]
Finished building: ../TestFortran2.f90

Building target: TestFortran2
Invoking: GNU Fortran Linker
gfortran  -o "TestFortran2"  ./TestFortran2.o   
Finished building target: TestFortran2


13:26:53 Build Finished. 0 errors, 4 warnings. (took 4s.364ms)

这些是在代码编辑器中显示警告的行,在第 51 到 55 行:


do i=1,N 
    signif(i) = (ABS(dsig2(i)-dsig1(i)))/dsig1(i) 
end do

signif_total = SUM(signif)

正如 Ian Bush 已经在上面评论的那样,您似乎还没有分配 signif 数组。它的大小似乎需要 N。因此,我将它添加到代码中,在其他分配的末尾进行分配,并将其也添加到释放列表中。

然后我清理了构建,并重新构建了它。结果是没有错误或警告。

如前所述,如果没有输入文件,我们将无法做更多事情,但在您的示例中,由于 N 的大小仅为 39 x 120 = 5,000 个元素,因此不太可能导致分配问题。

您始终可以使用 Stat 关键字检查分配是否成功:

Allocate(Array(Size),Stat=SuccessCode)

其他几件事。获得一个好的 IDE 是值得的,因为这将使编码变得更加容易。此外,在编写代码时,缩进代码并不是必须的,但它确实使以后更容易阅读。

【讨论】:

  • stat= 参数并没有看起来那么有用。 Linux 通常会为您提供比可用内存更多的虚拟内存,并且只会在第一次尝试使用该内存时崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-29
  • 2014-06-01
  • 2021-07-01
  • 2017-07-16
  • 2021-06-14
相关资源
最近更新 更多