im en utilisant C à l'appel Fortran, mon Fortran appelle tri() méthodeFortran Méthode de tri numérique recipies
*-----------------------------------------------------------------------
* SUBROUTINE sort(A,n)
* Subroutine de la librairie "Numerical Recipes"
* (C) Copr. 1986-92 Numerical Recipes Software
*-----------------------------------------------------------------------
SUBROUTINE sort(arr,n)
INTEGER n,M,NSTACK
REAL arr(n)
PARAMETER (M=7,NSTACK=50)
INTEGER i,ir,j,jstack,k,l,istack(NSTACK)
REAL a,temp
jstack=0
l=1
ir=n
1 if(ir-l.lt.M)then
do 12 j=l+1,ir
a=arr(j)
do 11 i=j-1,1,-1
if(arr(i).le.a)goto 2
arr(i+1)=arr(i)
11 continue
i=0
2 arr(i+1)=a
12 continue
if(jstack.eq.0)return
ir=istack(jstack)
l=istack(jstack-1)
jstack=jstack-2
else
k=(l+ir)/2
temp=arr(k)
arr(k)=arr(l+1)
arr(l+1)=temp
if(arr(l+1).gt.arr(ir))then
temp=arr(l+1)
arr(l+1)=arr(ir)
arr(ir)=temp
endif
if(arr(l).gt.arr(ir))then
temp=arr(l)
arr(l)=arr(ir)
arr(ir)=temp
endif
if(arr(l+1).gt.arr(l))then
temp=arr(l+1)
arr(l+1)=arr(l)
arr(l)=temp
endif
i=l+1
j=ir
a=arr(l)
3 continue
i=i+1
if(arr(i).lt.a)goto 3
4 continue
j=j-1
if(arr(j).gt.a)goto 4
if(j.lt.i)goto 5
temp=arr(i)
arr(i)=arr(j)
arr(j)=temp
goto 3
5 arr(l)=arr(j)
arr(j)=a
jstack=jstack+2
if(jstack.gt.NSTACK)pause 'NSTACK too small in sort'
if(ir-i+1.ge.j-l)then
istack(jstack)=ir
istack(jstack-1)=i
ir=j-1
else
istack(jstack)=j-1
istack(jstack-1)=l
l=i
endif
endif
goto 1
END
Et si je l'appelle la méthode de tri plusieurs fois, j'ai une erreur de segmentation dans cette méthode :(
il est ancien code, mais je suis en confiance parce qu'il vient de recipies numériques mais je me méfie de certaines choses, notamment cette ligne:.
if(jstack.gt.NSTACK)pause 'NSTACK too small in sort'
Si je suis dans ce cas, mon programme sera en pause? comment est-il possible qu'une méthode de tri le fasse?
Et si cette ligne est suspecte, comment puis-je faire confiance au code entier?
Est-ce que quelqu'un connaît un problème avec ce sous-programme de tri? est-ce que quelqu'un sait une autre méthode pour faire le tri dans Fortran? Parce que je peux remplacer cette méthode de tri par un autre mais je suis nouveau en fortran et je ne peux pas en écrire un autre.
J'ajoute que pas de problème si j'exécute cette méthode en mono thread, mais si je l'exécute en environnement multi thread, le problème est ici. désolé de ne pas mentionné quand j'ai écrit ma question mais je vois cela après l'avoir écrit.
DEBUG informations
current thread: [email protected]
[1] __lwp_kill(0x0, 0x6, 0x0, 0x6, 0xffbffeff, 0x0), at 0xff2caa58
[2] raise(0x6, 0x0, 0xff342f18, 0xff2aa378, 0xffffffff, 0x6), at 0xff265a5c
[3] abort(0x7400, 0x1, 0x0, 0xfcb78, 0xff3413d8, 0x0), at 0xff24194c
[4] os::abort(0x1, 0x0, 0xff011084, 0xfefdc000, 0x7d94, 0x7c00), at 0xfee7d3cc
[5] VMError::report_and_die(0x0, 0xff038640, 0xff031ff4, 0x1, 0xfee81b94, 0xff031ff4), at 0xfef0cd58
[6] JVM_handle_solaris_signal(0xb, 0xacffefe0, 0xacffed28, 0x8000, 0xff030fa0, 0x2013d8), at 0xfea73d48
[7] __sighndlr(0xb, 0xacffefe0, 0xacffed28, 0xfea7325c, 0x0, 0x1), at 0xff2c6e78
---- called from signal handler with signal 11 (SIGSEGV) ------
[8] sort_(0xfe2b1350, 0xfe2b135c, 0xfe2b1000, 0x1c00, 0x443bfc7b, 0xfe292484), at 0xfe27e498
[9] mediane_(0xa9c1624c, 0xacfff2ac, 0xa9c16060, 0xa9c05c34, 0x0, 0x19), at 0xfe27a38c
(dbx) frame 8
0xfe27e498: sort_+0x01d8: ld [%l4 + %l1], %f4
(dbx) disassemble
0xff2caa58: __lwp_kill+0x0008: bcc,a,pt %icc,__lwp_kill+0x18 ! 0xff2caa68
0xff2caa5c: __lwp_kill+0x000c: clr %o0
0xff2caa60: __lwp_kill+0x0010: cmp %o0, 91
0xff2caa64: __lwp_kill+0x0014: move %icc,0x4, %o0
0xff2caa68: __lwp_kill+0x0018: retl
0xff2caa6c: __lwp_kill+0x001c: nop
0xff2caa70: __lwp_self : mov 164, %g1
0xff2caa74: __lwp_self+0x0004: ta %icc,0x00000008
0xff2caa78: __lwp_self+0x0008: retl
0xff2caa7c: __lwp_self+0x000c: nop
en m solaris avec DBX => gdb sur
je tente d'inspecter adresse, mais ce que je peux taper avoir des informations intéressantes?
Après avoir ajouté l'option -g au compilateur f90, dans dbx je peux voir la valeur ou var et voir le résultat:
[email protected] ([email protected]) terminated by signal ABRT (Abort)
0xff2caa58: __lwp_kill+0x0008: bcc,a,pt %icc,__lwp_kill+0x18 ! 0xff2caa68
Current function is sort
578 temp=arr(k)
(dbx) print n
n = 19
(dbx) print arr
arr =
(1) 725.0666
(2) 741.5034
(3) 730.8196
(4) 754.3707
(5) 741.718
(6) 741.718
(7) 741.8914
(8) 745.9141
(9) 744.6705
(10) 741.718
(11) 745.8358
(12) 743.3788
(13) 746.2706
(14) 746.2706
(15) 750.1498
(16) 754.3707
(17) 754.3707
(18) 754.3707
(19) 748.2084
(dbx) print istack
istack =
(1) 7
(2) 12
(3) 17
(4) 18
(5) 8
(6) 9
(7) 1
(8) 4
(9) 0
(10) 0
(11) 0
(12) 0
(13) 0
(14) 0
(15) 0
(16) 0
(17) 0
(18) 0
(19) 0
(20) 0
(21) 0
(22) 0
(23) 0
(24) 0
(25) 0
(26) 0
(27) 0
(28) 0
(29) 0
(30) 0
(31) 0
(32) 0
(33) 0
(34) 0
(35) 0
(36) 0
(37) 0
(38) 0
(39) 0
(40) 0
(41) 0
(42) 0
(43) 0
(44) 0
(45) 0
(46) 0
(47) 0
(48) 0
(49) 0
(50) 0
(dbx) print jstack
jstack = -31648
(dbx)
comment son taht possible jstack un -31648 val! istack n'a que 50 éléments et istack (jstack) me retrun une valeur abd! comment c'est possible? :) merci par avance
Avez-vous essayé de remplacer le 'pause' une déclaration' de write'? L'instruction 'pause' est officiellement supprimée depuis Fortran 95 (mais toujours supportée par de nombreux compilateurs). Quel compilateur utilisez-vous? – Stefan
veuillez exécuter le code dans un débogueur pour pointer une ligne où il se sépare. – Peter
"Est-ce que quelqu'un sait une autre méthode pour faire le tri dans fortran?" Bien sûr, il existe plusieurs méthodes. Écrivez votre propre type de bulle, sorte de tas, type de Shell, peu importe. Ou utilisez 'qsort()' depuis la bibliothèque C standard, comme je le fais souvent. –