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

GCC中使用char/u8/s8变量出现值异常问题求助(附代码)

GCC下char/u8类型变量被意外清零问题的分析与解决

核心问题:scanf格式符与变量类型不匹配导致的未定义行为

你碰到的是C语言中典型的未定义行为——用%d格式符读取输入到u8/s8(本质是unsigned char/signed char)类型变量里。%d格式符要求传入int类型指针,但你传的是char类型指针,scanf会尝试向该位置写入int大小的数据,直接越界覆盖相邻内存。

你的全局变量NumberofElements和NumbertoSearchfor在内存中连续存放,所以读取NumbertoSearchfor时的越界操作直接把NumberofElements的内容冲成了0。Visual Studio表现“正常”只是巧合,它的内存布局刚好没让越界触发可见错误,但这依然是非法代码,随时可能出问题。

修复步骤

1. 替换为正确的scanf格式符

字符类型对应专门的格式符:

  • signed char(s8)用%hhd
  • unsigned char(u8)用%hhu

把代码里所有scanf调用改成对应格式:

// 读取数组元素个数
printf("Please enter the number of elements for the array: ");
scanf("%hhu", &NumberofElements);

// 读取数组元素
void Scan_Array() {
    for (u8 i = 0; i < NumberofElements; i++) {
        scanf("%hhu", &array[i]);
    }
}

// 读取要查找的数字
printf("\nPlease enter the number you want to search for: ");
scanf("%hhu", &NumbertoSearchfor);

2. 修正其他潜在问题

  • main函数返回值:标准C规定main必须返回int,把void main()改成int main(),并在函数末尾加return 0;
  • 递归调用main的内存泄漏:continuity里递归调用main会导致之前malloc的数组内存无法释放,改成循环结构:
int main() {
    while (1) {
        u8 NumbertoSearchfor, NumberofElements, * array = NULL;
        
        printf("Please enter the number of elements for the array: ");
        scanf("%hhu", &NumberofElements);

        array = (u8*)malloc(NumberofElements * sizeof(u8));

        printf("Please enter the values stored in the array:\n");
        Scan_Array(array);

        Sort(array);

        printf("\nPlease enter the number you want to search for: ");
        scanf("%hhu", &NumbertoSearchfor);

        Binary_Search(array, NumbertoSearchfor, NumberofElements);

        free(array); // 每次循环结束释放内存

        u8 cont = 0;
        printf("\nDo you want to continue? Y/N\n");
        scanf(" %c", &cont);
        if ((cont == 'Y') || (cont == 'y')) {
            continue;
        } else if ((cont == 'N') || (cont == 'n')) {
            printf("Thanks for using our program. Exiting ...");
            break;
        } else {
            printf("Invalid answer.");
        }
    }
    return 0;
}

(注:这里把全局变量改成局部变量,更符合规范,同时修改Binary_Search等函数为接收参数的形式,避免依赖全局变量)

  • Sort函数参数错误:原代码中Sort()定义无参数,但调用时传了array,修正为void Sort(u8 *array),或者去掉调用时的参数(若依赖全局array)。

3. 为什么volatile/static等方法没用?

这些操作只是偶然改变了变量的内存布局或存储位置,让越界覆盖没影响到NumberofElements,但根本问题没解决,所以效果不稳定,完全依赖编译器行为,不是真正的修复。

总结

只要把scanf的格式符改成对应字符类型的正确格式,就能彻底解决变量被意外清零的问题。同时修正代码中的非标准写法,保证跨编译器的兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:45:07