You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

COBOL素因数分解程序出现Invalid memory address error求助

解决COBOL素因数分解程序的内存引用错误(Signal 11)

错误现象

在JDoodle IDE(基于GNU Cobol 3.2.0)运行素因数分解程序时,触发以下内存异常:

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

程序目标:通过带余除法判断素数,素数直接输出;非素数调用子例程执行分解,最终输出2到100所有数的素因数分解结果。

问题根源分析

  1. 未初始化变量:主程序中divident未赋值就传入子例程,后续循环使用未定义数值引发非法内存访问。
  2. CALL参数不匹配:primzahl_check调用primfaktorzerlegung时,参数数量、类型与目标子例程的LINKAGE SECTION定义不一致,导致栈溢出。
  3. 数组容量不足:zahlenarray仅定义4个元素,无法容纳多因数的分解结果,引发索引越界。
  4. 循环逻辑错误:primzahl_check的终止条件divident = 3逻辑混乱,未初始化的变量可能导致死循环,最终触发内存异常。
  5. 素数判断逻辑错误:原代码中divident = divisor的判断条件无法正确识别素数。

修复后的完整代码

主程序(初始化起始值)

identification division.
program-id. main_methode.
data division.
working-storage section.
01 divident pic 9(5) value 2.  *> 初始化起始值为2,对应需求的2到100范围
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).
working-storage section.
    01 zahlenarray.
    05 zahlen occurs 10 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 > 100  *> 修正终止条件:循环到100结束
    
        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 divisor > divident then  *> 修正素数判断:遍历完所有除数未整除则为素数
            display ' '
            display divident " ist eine Primzahl"
            display ' '
        else
            subtract 1 from divisor  *> 回退到最后一个能整除的除数
            call 'primfaktorzerlegung' using divident divisor zahlenarray i quotient
        
        add 1 to divident
        
    end-perform.
    
end program primzahl_check.

素因数分解子例程(修正循环与索引)

identification division.
program-id. primfaktorzerlegung.
data division. 
    linkage section.
    01 input-divident pic 9(5).  *> 重命名避免变量冲突
    01 start-divisor pic 9(5).
    01 zahlenarray.
    05 zahlen occurs 10 times indexed by z_idx.
      10 z_zahl pic s9(5).
    01 i pic 9(5).
    01 quotient pic 9(5).
working-storage section.
    01 current-divident pic 9(5).
    01 current-divisor pic 9(5).
    01 rest pic 9v9.

procedure division using input-divident start-divisor zahlenarray i quotient.

    *> Primfaktorzerlegung
    move input-divident to current-divident
    move start-divisor to current-divisor
    move 1 to z_idx
    
    display ' '
    display "Primfaktorzerlegung von " input-divident ":"
    
    perform until current-divident = 1  *> 终止条件:被除数变为1时完成分解
        
        divide current-divident by current-divisor giving quotient remainder rest
        
        if rest = 0 then
            move current-divisor to z_zahl(z_idx)
            display current-divisor " " with no advancing
            move quotient to current-divident
            add 1 to z_idx
        else
            add 1 to current-divisor
            
    end-perform.
    
    display ' '
    display ' '.
end program primfaktorzerlegung.

关键修复点

  • 所有传入子例程的变量必须提前初始化
  • CALL语句参数的数量、顺序、类型必须与目标子例程的LINKAGE SECTION完全匹配
  • 根据实际需求设置数组容量,避免索引越界
  • 修正素数判断和循环终止条件,确保逻辑闭环且无死循环

内容的提问来源于stack exchange,提问作者Luka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 21:14:58