runtime-errorcobolgnucobol

Invalid memory address error in my COBOL application


I wrote this COBOL application to perform a prime factorization, it is not yet completed.

When I run the code, I get this error/output:

Programm zur Darstellung der Primfaktorzerlegung mit einer gegebenen Zahl
 


attempt to reference invalid memory address (signal)


 Last statement of "primfaktorzerlegung" unknown
 Last statement of "primzahl_check" unknown
 Last statement of "main_methode" unknown
 Started by ./jdoodle
Command terminated by signal 11

I use JDoodle as my IDE and it uses GNUCobol 3.2.0.

The code that I wrote performs a basic division with remainder to check if there is a prime number, if it is a prime number the output will be the prime number, if it is not a prime number, which is checked in a subroutine, the code will perform a prime factorization.

identification division.
program-id. main_methode.
data division.
working-storage section.
01 divident pic 9(5).
01 rest pic 9v9.
01 divisor pic 9(5).
01 ergebnis pic 9(5).
    
*> Kurze Erklärung:
*> Primfaktorzerlegung der Zahl 20.
*> 20 / 2 = 10
*> 10 / 2 = 5
*> 5 / 2 = 2.5
*> Also lautet die Primfaktorzerlegung: von 20 = 2 *> 2 *> 5
*> Bis zu der Zahl wo die Division einen Rest ergibt.

*> Eine Liste für alle Zahlen von 2 bis 100 mit den dazugehörigen Zerlegungen ausgeben

procedure division.
    display 'Programm zur Darstellung der Primfaktorzerlegung mit einer gegebenen Zahl'.
    display ' '.
    
    call 'primzahl_check' using divident rest divisor ergebnis.

end program main_methode.




identification division.
program-id. primzahl_check.
data division.
    linkage section.
    01 divident pic 9(5).
    01 rest pic 9v9.
    01 divisor pic 9(5).
    01 ergebnis pic 9(5).
    01 zerlegt pic x(5).
    01 priv_divident pic 9(5).
    01 zahlenarray.
    05 zahlen occurs 4 times indexed by z_idx.
      10 z_zahl pic s9(5).
    01 i pic 9(5).
    01 quotient pic 9(5).
    *> Überprüfen ob es bei der Zahl um eine Primzahl handelt
procedure division using divident rest divisor ergebnis.
    perform until divident = 3
    
        move 2 to divisor
        move 1 to rest 
    
        perform until rest = 0 or divisor >= divident
            
            divide divident by divisor giving ergebnis remainder rest
            
            add 1 to divisor
            
        end-perform
        
        if divident = divisor then
            display ' '
            display divisor " ist eine Primzahl"
            display ' '
        else
            call 'primfaktorzerlegung' using divisor zerlegt divident priv_divident zahlenarray i quotient
        
        
        add 1 to divident
        
    end-perform.
    
end program primzahl_check.




identification division.
program-id. primfaktorzerlegung.
data division. 
    linkage section.
    01 divisor pic 9(5).
    01 zerlegt pic x(5).
    01 divident pic 9(5).
    01 priv_divident pic 9(5).
    01 zahlenarray.
    05 zahlen occurs 4 times indexed by z_idx.
      10 z_zahl pic s9(5).
    01 i pic 9(5).
    01 quotient pic 9(5).
    01 rest pic 9v9.

procedure division using divisor zerlegt divident priv_divident zahlenarray i quotient.

    *> Primfaktorzerlegung
    move 2 to divisor.
    move 'false' to zerlegt.
    
    *> Ursprünglicher Divident speichern, in diesem Fall die 20
    move divident to priv_divident
    move 1 to z_idx
    move 2 to i
    move priv_divident to z_zahl(z_idx)
    move 2 to divident.
    
    perform until zerlegt = 'true'
        
        divide divident by divisor giving quotient remainder rest
        
        move quotient to divident
            
        if rest = 0 then
               
            move i to z_idx
            
            move divisor to z_zahl(z_idx)
                
            add 1 to i
            
        else
            move i to z_idx
            
            move quotient to z_zahl(z_idx)
                
            move 'true' to zerlegt
            
        *> call 'zahlen_ausgeben' using z_zahl
            
    end-perform.
end program primfaktorzerlegung.

Any help would be appreciated.

Searching documentation, changing the code to make it work.


Solution

  • Variables defined in the Linkage Section are not allocated automatically like variables in Working-Storage and Local-Storage sections. Either you must allocate them explicitly with an ALLOCATE statement or you must reference them in the CALL statement that invokes your program.

    When you CALL program primfaktorzerlegung, you do not pass the rest variable. You do pass the zahlenarray, i, and quotient variables, but they are first defined in the Linkage Section of primzahl_check and were not passed on the CALL from main_methode and so they have no storage automatically associated with them.

    I suggest defining zahlenarray, i, and quotient variables in the Working-Storage or Local-Storage Section of program primzahl_check, and adding rest to the calling parameters when you CALL program primfaktorzerlegung.

    You also have IF statements in both primzahl_check and primfaktorzerlegung which have no END-IF. I'm not sure if GNU COBOL is handling that by presuming the IF is terminated by the full stop at the end of the END-PERFORM or if that is another problem, but I thought I'd point it out.