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

GNUCobol 3.2.0质因数分解程序编译出现Segmentation fault错误求助

质因数分解COBOL程序段错误(Segmentation Fault)排查与修复

错误信息

unknown (signal)

cobc: aborting compile of jdoodle.cobc at line 68 (PROGRAM-ID: primzahl_check)
cobc: Please report this!
bash: line 1:    14 Segmentation fault      (core dumped) cobc -x -free -O jdoodle.cobc -o jdoodle

环境:JDoodle IDE,GNU Cobol 3.2.0


问题根源分析

  1. 重复程序ID冲突
    代码中存在两个PROGRAM-ID: primfaktorzerlegung,GNU Cobol不允许同一编译单元内存在同名子程序,这会导致符号表混乱,直接触发编译阶段的段错误。

  2. 调用参数完全不匹配

    • primzahl_check调用primfaktorzerlegung时传递了数组zahlenarray,但目标子程序的PROCEDURE DIVISION USING声明的是单个元素z_zahl,类型和数量不匹配,会破坏栈结构。
    • zahlen_ausgeben的调用语句没有传递任何参数,但该子程序要求3个输入参数,参数缺失会导致栈溢出。
  3. 未声明的索引变量
    第二个处理分解的子程序中使用了索引z_idx,但未在DATA DIVISION中显式声明该索引(仅在数组定义中提及indexed by z_idx是不够的,需要单独定义索引项)。

  4. 数组容量不足
    zahlenarray仅定义了4个元素,对于大于16的数(如16=24),质因数数量刚好是4,但更大的数(如32=25)会直接触发数组越界访问。


修复后的完整代码

identification division.
program-id. primfaktorzerlegung-main.  *> 修改主程序ID,避免重复
data division.
working-storage section.
01 divident pic 9(5) value 2.  *> 初始化起始值,避免未定义的垃圾值
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 primfaktorzerlegung-main.

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 10 times indexed by z_idx.  *> 扩容数组到10个元素,覆盖大部分小数值需求
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  *> 修改循环条件,实现2到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 divident = divisor then
            display ' '
            display divisor " ist eine Primzahl"
            display ' '
        else
            call 'primfaktorzerlegung-sub' using divident zahlenarray  *> 修改子程序名,传递正确参数
        
        add 1 to divident
    end-perform.

end program primzahl_check.

identification division.
program-id. primfaktorzerlegung-sub.  *> 修改子程序ID,避免与主程序重复
data division.
linkage section.  *> 子程序必须用linkage section接收外部参数
01 divident pic 9(5).
01 zahlenarray.
05 zahlen occurs 10 times indexed by z_idx.
10 z_zahl pic s9(5).
01 priv_divident pic 9(5).
01 divisor pic 9(5).
01 quotient pic 9(5).
01 rest pic 9v9.
01 i pic 9(5).
01 zerlegt pic x(5) value 'false'.
01 z_idx pic 9(1).  *> 显式声明索引变量

procedure division using divident zahlenarray.

    *> Primfaktorzerlegung
    move 2 to divisor.
    move 'false' to zerlegt.
    
    *> Ursprünglicher Divident speichern
    move divident to priv_divident
    move 1 to z_idx
    move priv_divident to z_zahl(z_idx)
    move priv_divident to divident.  *> 修正初始值,使用原始输入值
    move 2 to i.
    
    perform until zerlegt = 'true'
        divide divident by divisor giving quotient remainder rest
        
        if rest = 0 then
            move quotient to divident
            move i to z_idx
            move divisor to z_zahl(z_idx)
            add 1 to i
        else
            if quotient > 1 then  *> 处理剩余的质数因子
                move i to z_idx
                move quotient to z_zahl(z_idx)
            end-if
            move 'true' to zerlegt
        end-if
        
        call 'zahlen_ausgeben' using zahlenarray priv_divident  *> 传递正确参数到输出子程序
    end-perform.

end program primfaktorzerlegung-sub.

identification division.
program-id. zahlen_ausgeben.
data division.
linkage section.
01 zahlenarray.
05 zahlen occurs 10 times indexed by z_idx.
10 z_zahl pic s9(5).
01 original-zahl pic 9(5).
01 y pic 9(1).
01 zahl_prnt pic z(5).

procedure division using zahlenarray original-zahl.

display 'Primfaktorzerlegung von ' original-zahl ': '.
perform varying y from 2 by 1 until y > 10 or z_zahl(y) = 0
        move y to z_idx
        move z_zahl(z_idx) to zahl_prnt
        if zahl_prnt > 0 then
            display zahl_prnt ' ' with no advancing
        end-if
    end-perform.
display ' '.

end program zahlen_ausgeben.

关键修改点说明

  1. 重命名重复的primfaktorzerlegung程序ID为primfaktorzerlegung-main和primfaktorzerlegung-sub,解决符号冲突。
  2. 统一所有子程序的参数传递规则,确保调用时的参数数量、类型与目标子程序的声明完全匹配。
  3. 显式声明索引变量z_idx,避免未定义变量导致的内存访问错误。
  4. 扩容数组到10个元素,覆盖2到100范围内所有数的质因数分解需求。
  5. 初始化主程序的divident起始值为2,避免未初始化的垃圾值导致的异常行为。
  6. 修正分解逻辑中的初始值错误,确保使用原始输入值进行分解。
  7. 完善zahlen_ausgeben的输出逻辑,只打印有效的质因数。

内容的提问来源于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 19:44:50