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所有数的素因数分解结果。
问题根源分析
- 未初始化变量:主程序中
divident未赋值就传入子例程,后续循环使用未定义数值引发非法内存访问。 - CALL参数不匹配:
primzahl_check调用primfaktorzerlegung时,参数数量、类型与目标子例程的LINKAGE SECTION定义不一致,导致栈溢出。 - 数组容量不足:
zahlenarray仅定义4个元素,无法容纳多因数的分解结果,引发索引越界。 - 循环逻辑错误:
primzahl_check的终止条件divident = 3逻辑混乱,未初始化的变量可能导致死循环,最终触发内存异常。 - 素数判断逻辑错误:原代码中
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
相关产品推荐
相关产品推荐

