Debug my program please.



I have an error in to recursive function aggiungi(i)at first recursion.
Error: the instruction attemp read from location 000000.
Is right that is null, but why "if (.not. associated(i)) then" make this error?


!Variabili Globali
module Var
		
	!Struttura
	type Word
    	character(50) :: Parola
        !character,allocatable :: Parola	
        integer :: Freq

    end type Word

	type Albero
    	type (Word) E
        type (Albero), pointer :: s
        type (Albero), pointer :: d
    end type Albero

		character(50)::Parola

   	Type (Albero),pointer :: Tree, TreeF

end module Var

!Funzione che effettua la scansione del file per individuare le parole
Subroutine Scansione()

	use Var
	!Variabili
	character :: C
    character(len=74) :: Alf, Alfabeto
	!Dichiarazione e inizializzazione variabile i
	integer :: i = 1
    integer :: d = 1
    logical :: FineParola
    type(Albero),pointer :: x

 Interface
	Recursive Function Aggiungi(i) Result (x)
	use Var
    Type(Albero),pointer :: i
    Type(Albero),pointer :: x
    end function Aggiungi
end Interface

Alf="abcdefghilmnopqrstuvzxyjkw+-++¦-ÊË++ABCDEFGHILMNOPQRSTUVZXYJKWÓßÞÚýÝ=¾¨·"
Alfabeto= "abcdefghilmnopqrstuvzxyjkwàáèéìíòóùúabcdefghilmnopqrstuvzxyjkwàáèéìíòóùú"
!Identifica se carattere letto è un segno di punteggiatura o no

rewind(UNIT=4) !Riavvolgimento file

!Inizializzazione parola
Parola=''
IOSS=0
do while(IOSS .ne. -1) !Ripete fino alla fine del file
!ADVANCE='NO' obbliga la read a leggere sempre sulla stessa riga.
read (4,'(A)',ADVANCE='NO',IOSTAT = IOSS)C !Lettura del carattere
FineParola =.true.
!Controllo del carattere a-z o A-Z


		do while(i<=72)

       		if ((Alfabeto(i:i))== C) then
					!Concatenzazione dei caratteri per formare la parola
                    print *,i ,"->"//(Alfabeto(i:i))
                    print *,C
					Parola(d:) = C
                    d=d+1!Incremento l'indice
					FineParola = .false.
					exit	
			end if
            i=i+1			
		end do
		i=1
			if ((FineParola) .and. (Parola .ne. ""))then
				print *,'PAROLA: '//parola
				i=1!Reinizializzazione indice
                d=1
				! Reinizializzazione della parola	
                if (.not. associated(Tree)) then

					Tree => Aggiungi(Tree)
					
				else
      				
					x => Aggiungi(Tree)

				end if
                Parola=''
			endif
	
	end do

	close(4)
end subroutine

!Funzione di aggiunta di un nodo all'albero
Recursive Function Aggiungi(i) Result (x)
	use Var
    Type (Albero), pointer :: i
    Type (Albero), pointer :: x
ERROR
if (.not. associated(i)) then

	!Creazione nuovo nodo dell'albero
	allocate(i)
	!Imposto il valore dei puntatori ai nodi figli
	nullify(i%d)
    nullify(i%s)
	!Impostazione della frequenza
	i%E%Freq = 1
	!Allocazione della memoria per la stringa contenete la parola
	i%E%Parola = Parola

else
	!Comparazione della parola
	!Se le parole sono uguali incremento il valore della frequenza
	if (i%E%Parola == Parola) then
		i%E%Freq = i%E%Freq + 1
	end if

	if ( i%E%Parola > Parola) then
		i%s => Aggiungi(i%s)
	end if
	if (i%E%Parola < Parola) then
		i%d => Aggiungi(i%d)
	end if

end if
x=>i	
end Function Aggiungi

!Funzione che crea l'abero delle frequenze partendo dall'abero ordinato per alfabeto
Recursive subroutine CreaAlberoF(t)
use Var
type(Albero), pointer :: t
type(Albero), pointer :: z


	interface
       Recursive Function AggiungiF(i, P, F) Result(x)
        use Var
        type(Albero), pointer :: i
        Type(Albero), pointer :: x
        Character (50) :: P
        integer :: F
       end function
	end interface



	if (associated(t)) then
	
		if ((.not. associated(t%s)) .and. (.not. associated(t%d))) then
		
			!Richiamo della funzione che aggiunge un nodo all'albero delle frequenze
			if (.not. associated(TreeF)) then
			
				TreeF => AggiungiF(TreeF,t%E%Parola,t%E%Freq)
			
			else
			
				z => AggiungiF(TreeF,t%E%Parola,t%E%Freq)

			end if


else

call CreaAlberoF(t%s)
!Richiamo della funzione che aggiunge un nodo all'albero delle frequenze
if (.not. associated(TreeF)) then

TreeF => AggiungiF(TreeF,t%E%Parola,t%E%Freq)

else

z => AggiungiF(TreeF,t%E%Parola,t%E%Freq)
end if

call CreaAlberoF(t%d)
end if
end if
end subroutine CreaAlberoF


Recursive Function AggiungiF(i, P, F) Result(x)
	use Var
    type(Albero),pointer :: i
    Type(Albero),pointer :: x
    Character (50) :: P
    integer :: F

	if (.not. associated(i)) then
	
		!Creazione nuovo nodo dell'albero
		allocate(i)
		!Imposto il valore dei puntatori ai nodi figli
		nullify(i%d)
		nullify(i%s)
		!Impostazione della frequenza
		i%E%Freq = F
		!Copia della stringa
		i%E%Parola = P
	else
	
		!Comparazione Frequenza
		if ( i%E%Freq < F) then
		
			i%s = AggiungiF(i%s, P, F)
		
		else
		
			i%d = AggiungiF(i%d, P, F)

		end if
		
	end if
    x=>i
end function AggiungiF


!Funzione di stampa dell'albero Recursive subroutine Print(t) use Var type (Albero),pointer :: t integer :: Count = 0

	if (associated(t)) then
     	print *,"->"//t%E%parola
		if (.not.(associated(t%s) .and. associated(t%d))) then
		
			if (Count == 10 ) then
			
				print *,'Premere un tasto per continuare...'
            	Count=0
            	read *
			
			else
			
				Count = COunt +1
			
			!Stampa della parola
			print *, 'PAROLA: ',t%E%Parola // 'FREQUENZA: ',t%E%Freq

			end if
		
		else
		
			!Richiamo della funzione sul ramo sinistro
			call Print(t%s)
			
			if (Count == 10 ) then
			
				print *,'Premere un tasto per continuare...'
            	Count=0
            	read *
			
			else
			
				Count = Count + 1
			
			!Stampa della parola
			print *, 'PAROLA: ',t%E%Parola // 'FREQUENZA: ',t%E%Freq
			
			!Richiamo della funzione sul ramo destro
			call Print(t%d)
            end if
		end if
	end if
end subroutine Print

Program Testo
	use Var
    !Tutte le variabili devono essere esplicite
	Implicit None

    	interface
		Recursive subroutine CreaAlberoF(t)
        use Var
    	type(Albero), pointer :: t
    	type(Albero), pointer :: z
        end subroutine CreaAlberoF
	end interface
    interface
    	Recursive subroutine Print(t)
        use Var
		type (Albero),pointer :: t
		integer :: Count
        end subroutine Print
    end interface

	!Dichiarazione variabili
	character (50) :: NomeFile


!Variabile utilizzata per leggere la lunghezza della stringa NomeFile integer :: lungh = 0

	integer :: iScelta = 0

	integer :: Stato

	nullify (Tree)
    nullify (TreeF)


!MAIN
print *,"Avvio del programma"

60 print *,"Inserire il nome del file di testo che si desidera utilizzare (Esempio: Testo.txt)"


	!Inizializzazione variabili
	
   	lungh = 0
	

	!Lettura del nome del file da aprire	
	do while ((lungh < 4).OR.(lungh > 50))
    	read *,NomeFile !Lettura del nome del file
        lungh = len_trim(NomeFile)
	end do

	!Apre il file in scrittura

open(UNIT=4,FILE=NomeFile,STATUS='old',ACTION='read',ACCESS='sequential', ERR=70, IOSTAT=Stato)

!Gestione errore nell'accesso al file
70 if(Stato == 128) then
print *,"File non trovato"
Goto 60
else
if(Stato > 0) then
print *,"Si è verificato un errore durante l'accesso al file. Il programma sarà terminato."
goto 111
end if
end if


do while(iScelta /= 5)

!Menù
print *," 1- Scansione del file di testo"
print *," 2- Creazione della lista delle parole ordinato per frequenza"
print *," 3- Stampa a video della lista delle parole ordinato per frequenza"
print *," 4- Stampa a video della lista delle parole ordinato per ordine alfabetico"
print *," 5- Esci"


do while(iScelta /= 1 .and. iScelta /= 2 .and. iScelta /= 3 .and. iScelta /= 4 .and. iScelta /= 5)
read (*,*)iScelta
end do

!Blocco di scelta
select case(iScelta)

case (1):
call Scansione()
print *,"Scansione EFFETTUATA!"


            case (2):
            			call CreaAlberoF(Tree)
			case (3):
            			call Print(TreeF)
			case (4):
            			call Print(Tree)
			case default:
					exit
		end select
        !Rimetto a 0 la variabile per evitare un ciclo infinito
        iScelta = 0
	end do
 111 end program Testo
.



Relevant Pages

  • Re: Timing Rescordset
    ... The recursive function I am using first check to see if it has something, ... avoid levels of recursion that lack substantial advantage. ... XML authors use the same node name in a different heirarchy? ... To reconstruct, you'll have to query the db for each level, in much the same ...
    (microsoft.public.data.ado)
  • Re: Traversing shallow CTreeCtrl
    ... Why not write a recursive function ... that takes exactly on HTREEITEM ... number of levels usually ends up being more difficult than a simple recursion. ... LvlThreeNode = MyTree.GetNextItem; ...
    (microsoft.public.vc.mfc)
  • Re: Any use for recursion?
    ... popped back off the stack, the program counter being changed again. ... Also, if the recursion is deep, e.g. 16 levels deep, then it results ... can be done with a plain loop can be done with a recursive function. ...
    (comp.programming)
  • Re: Iteration in lisp
    ... recursive function can run out of stack since CL does not guarantee ... archives of this newsgroup for the TAILPROG macro, ... tail recursion with syntax resembling FLET or LABELS can be obtained ...
    (comp.lang.lisp)
  • Re: error handlling in recursive function
    ... has failed and you want to set the error flag and return it to the ... calling function(the one which called the recursive function in the ... Use setjmp (before entering recursion) and longjmp to hop back on ... Ok, global variables are EVIL, ...
    (comp.lang.c)