Ошибка сегментации - неверная ссылка на память в фортране - PullRequest
0 голосов
/ 04 февраля 2020

Я пытаюсь использовать 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 на выходе, но мой код не может рассчитать дальнейший результат.

Может кто-нибудь помочь мне с этим? Спасибо. Я предполагаю, что размер массива, который я использовал, слишком велик.

1 Ответ

0 голосов
/ 08 февраля 2020

Я взял ваш код и загрузил его в Eclipse IDE, используя бесплатный GNU Fortran.

Я запустил 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)

Как уже прокомментировал Ян Бу sh, похоже, что вы не выделили массив signif . Кажется, он должен быть размером N . Итак, я добавил его в код, выделил в конце других выделений и добавил в список освобождения.

Затем я очистил сборку и перестроил все. Результатом являются отсутствие ошибок или предупреждений.

Как уже отмечалось, мы не можем сделать больше без входного файла, но, поскольку в вашем примере N имеет размер только 39 x 120 = 5000 элементов, это вряд ли вызовет проблема для распределений.

Вы всегда можете проверить успешность размещения, используя ключевое слово Stat:

Allocate(Array(Size),Stat=SuccessCode)

Несколько других вещей. Стоит получить хорошую IDE, так как это значительно облегчит кодирование. Кроме того, когда вы кодируете, не обязательно делать отступы для своего кода, но это значительно облегчает его чтение позже.

...