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

C语言编写四则运算程序触发SIGSEGV段错误原因排查

C语言四则运算程序段错误根因及修复

核心触发原因

段错误的直接诱因是scanf函数传参错误,所有scanf调用均未传入变量的内存地址,而是直接传入未初始化的变量本身。scanf的工作机制是将用户输入的值写入参数指定的内存地址,未初始化的局部变量存储的是随机垃圾值,scanf会把这个随机值当作目标内存地址尝试写入,触发非法内存访问,最终抛出SIGSEGV段错误。

具体代码疏漏

  • 三处scanf调用全部遗漏取地址运算符&:
    原错误写法:
    scanf("%d", vIn_a); 
    scanf("%d", vIn_b);
    scanf("%c", vOperator);
    
    正确写法需要给每个传入的变量前加&,传递变量地址。
  • 输入逻辑存在缓冲区残留问题:输入第二个整数后按下的回车换行符会残留在标准输入缓冲区,会被第三个读取字符的scanf直接捕获,导致程序不会等待用户输入运算符,直接读取到换行符,后续switch分支无法匹配,运算结果变量为未初始化的随机值。
  • 缺少非法输入、除零错误的兜底判断,鲁棒性不足。

gdb报错说明

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7c60d36 in ?? () from /usr/lib/libc.so.6
该报错指向C标准动态库libc.so.6是因为段错误实际触发在scanf的库函数实现逻辑中,系统未加载libc的调试符号因此显示??,并非标准库本身存在故障,根因是传入的非法参数。

修复后完整代码

#include <stdio.h>

int main () {
    int vIn_a, vIn_b, vIn_c;
    char vOperator;
    
    printf("Please enter a number\n");
    scanf("%d", &vIn_a); 
    printf("Please enter a number\n");
    scanf("%d", &vIn_b);
    printf("Please enter a Operator\n");
    // 格式串开头的空格用于跳过缓冲区中残留的换行、空格等空白字符
    scanf(" %c", &vOperator);

    switch(vOperator){
        case '+':
            vIn_c = vIn_a + vIn_b; 
            break;
        case '-':
            vIn_c = vIn_a - vIn_b;
            break;
        case '/':
            // 增加除零判断避免运行时错误
            if (vIn_b == 0) {
                printf("Error: division by zero\n");
                return 1;
            }
            vIn_c = vIn_a / vIn_b;
            break;
        case '*':
            vIn_c = vIn_a * vIn_b;
            break;
        default:
            printf("Error: invalid operator\n");
            return 1;
    }
    printf("Result: %d %c %d = %d\n", vIn_a, vOperator, vIn_b, vIn_c);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:39:30