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

为什么C语言中scanf读取数组后访问元素会触发段错误?

段错误原因分析及修复建议

一、触发段错误的核心原因

1. 未限制输入长度导致缓冲区溢出

你声明的input1是栈上分配的30字节字符数组,而scanf("%s", input1)没有设置输入长度限制。如果输入的字符数超过29(C字符串需要末尾的\0作为结束标记,所以最多只能存29个有效字符),超出的内容会直接写入数组之外的栈内存区域,破坏栈帧的结构(比如覆盖函数返回地址、其他变量的存储空间)。

这种情况下,printf("%s", input1)可能还能暂时输出内容(因为字符串的\0可能还没被完全覆盖),但当执行到char current = input1[0];时,栈已经被破坏,数组的起始地址或内存内容已经异常,从而触发段错误。

2. 循环逻辑存在无限遍历风险

如果缓冲区溢出导致字符串的\0结束符被覆盖,你的循环会持续执行:counter不断递增,反复访问input1[counter],最终越界访问到非法内存区域,同样会触发段错误。

二、修复方案

  1. 限制scanf的输入长度
    将scanf("%s", input1)修改为scanf("%29s", input1),强制最多读取29个字符,预留一个字节给\0,从根源避免缓冲区溢出。

  2. 优化循环遍历逻辑
    改用指针遍历的方式,更简洁且避免计数器越界的问题,同时修正isdigit的参数类型(避免传入负数值导致未定义行为):

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    
    int main(){
        char input1[30];
        scanf("%29s", input1);
        printf("%s\n", input1);
    
        char *current = input1;
        while (*current != '\0'){
            // 把char转为unsigned char,避免isdigit处理负数值
            if (isdigit((unsigned char)*current) || strchr("+-*/", *current)){
                current++;
            } else {
                printf("invalid input\n");
                exit(1);
            }
        }
    
        return 0;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 11:55:34