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

未使用数组b[3]缺失致C程序运行异常,求排查与修复

问题分析与修复

你遇到的问题是典型的栈内存越界写入导致的行为异常,而char b[3]只是碰巧充当了"缓冲区",掩盖了代码中的潜在错误。下面一步步拆解原因和解决方案:

核心问题原因

1. 变量x的类型与数值错误

  • x被声明为unsigned char,这是一个8位无符号类型,最大值仅为255。当你多次执行操作导致x累加超过255时,会发生数值溢出,x会绕回成一个小数值(比如250+10=260,260 mod 256=4),这会让代码错误地认为x<=100,继续执行越界的内存写入。
  • 初始x=3是正确的(对应"man"的3个字符长度),但case 0中你把x设为2,这导致x始终和字符串的实际长度不一致,后续所有依赖x的操作都会出错。

2. case4-6中的增量与循环逻辑错误

  • 比如case4中,你想给"man"前面加上"spider"变成"spiderman",实际需要增加的长度是6("spider"的字符数),但你写了x+=7,这让x比实际字符串长度多1,导致循环操作越界。
  • 循环移动字符的逻辑也有问题:你从i=x开始移动,但x是字符串长度(不含'\0'),这会导致多移动一个位置,写入到数组a的边界之外。

3. 栈内存越界的影响

当代码越界写入a数组时,在有b[3]的情况下,越界的数据会写入到b的内存空间(因为栈上变量是连续分配的),不会影响其他关键变量;但移除b[3]后,越界写入直接覆盖了x或者f的内存,导致x的值被篡改,进而让后续的strcat或字符移动操作错误地覆盖了a的起始内容,出现输入1却输出"spider"的情况。

修复后的代码

下面是修正后的代码,解决了所有上述问题:

#include <stdio.h>
#include <string.h>

int main() { // 标准main函数返回int类型
    char a[100] = "man";
    // 移除了无用的b[3]
    printf("A man is bitten by a spider and becomes spiderman.\n" 
           "So in this motive start making stuff.\nTo end the program " 
           "just click X on top right of the window\n\n");
    printf("When you create sth really big, you go back to only having " 
           "a man.\n\n");
    
    unsigned char f = 1;
    int x = 3; // 改用int类型,避免溢出,初始值对应"man"的长度
    int i; // 循环变量改用int,避免unsigned的边界问题

    while(1){
        printf("You have a %s\n", a);
        printf("Press:\n" 
               "\t1 for what you have to bite a spider.\n" 
               "\t2 for what you have to bite a man.\n" 
               "\t3 for what you have to bite spiderman.\n" 
               "\t4 for what you have to get bitten by a spider.\n" 
               "\t5 for what you have to get bitten by a man.\n" 
               "\t6 for what you have to get bitten by spiderman.\n" 
               "\t0 to go from the start\n");
        scanf("%hhu", &f);

        switch(f){
            case 0: 
                strcpy(a, "man"); 
                x = 3; // 修正x的值为3
                break;
            case 1: 
                if(x + 6 <= 99){ // 确保有足够空间(留1位给'\0')
                    strcat(a, "spider");
                    x += 6;
                }
                break;
            case 2: 
                if(x + 3 <= 99){
                    strcat(a, "man");
                    x += 3;
                }
                break;
            case 3: 
                if(x + 9 <= 99){
                    strcat(a, "spiderman");
                    x += 9;
                }
                break;
            case 4: 
                if(x + 6 <= 99){ // 插入"spider"到前面,增加6个字符
                    // 把原字符串后移6位,从最后一个字符开始
                    for(i = x - 1; i >= 0; i--){
                        a[i + 6] = a[i];
                    }
                    // 写入"spider"到前6位
                    strncpy(a, "spider", 6);
                    x += 6;
                }
                break;
            case 5: 
                if(x + 3 <= 99){ // 插入"man"到前面,增加3个字符
                    for(i = x - 1; i >= 0; i--){
                        a[i + 3] = a[i];
                    }
                    strncpy(a, "man", 3);
                    x += 3;
                }
                break;
            case 6: 
                if(x + 9 <= 99){ // 插入"spiderman"到前面,增加9个字符
                    for(i = x - 1; i >= 0; i--){
                        a[i + 9] = a[i];
                    }
                    strncpy(a, "spiderman", 9);
                    x += 9;
                }
                break;
        }
        // 检查是否超过数组容量(最多99个字符)
        if(x > 99){ 
            strcpy(a, "man"); 
            x = 3; 
        }
    }
    return 0; // 标准main返回0
}

关键修复点说明

  1. x改为int类型:避免了无符号溢出问题,能正确跟踪字符串长度。
  2. 修正x的初始值和case0的赋值:确保x始终等于字符串的实际字符长度(不含'\0')。
  3. 修正case4-6的增量与循环:
    • 增量改为对应插入字符串的实际长度(6、3、9)。
    • 循环从原字符串的最后一个字符(x-1)开始后移,避免越界写入。
  4. 增加空间检查:所有操作前先判断是否有足够的数组空间(留1位给字符串终止符'\0'),彻底避免越界。
  5. 标准化main函数:改为int main()并返回0,符合C语言标准。

现在你可以移除b[3],程序也能正常运行,输入1时会正确输出"You have a manspider"。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:54:12