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

C语言栈缓冲区溢出的中途检测、修复及正常执行方法咨询

C语言栈缓冲区溢出的检测、修复与执行恢复方案

问题场景

用户代码(修正character为char笔误后):

char dform[12];
strcpy(dform, "june-11-2024"); // 该字符串含终止符共12字节,超出数组容量
checkdate(dform); // 调用子程序时触发栈缓冲区溢出

注:dform[12]的有效容量为11个字符加1个字符串终止符'\0',输入字符串长度超标导致溢出,需在子程序中检测并修复,实现类似C#异常处理的执行恢复效果。


一、栈缓冲区溢出的检测方法

C语言无内置栈溢出检测机制,需手动实现或借助编译特性:

  • 传递数组容量并检测字符串长度
    在调用子程序时同时传入数组的有效容量,子程序内通过strlen()计算实际字符串长度,与容量对比判断溢出:

    void checkdate(char *dform, size_t max_valid_len) {
        size_t actual_len = strlen(dform);
        if (actual_len > max_valid_len) {
            // 触发溢出检测逻辑
            printf("检测到溢出:字符串长度%zu,超出最大允许长度%zu\n", actual_len, max_valid_len);
        }
        // 原有日期检查逻辑...
    }
    

    调用时传入有效容量:

    checkdate(dform, sizeof(dform)/sizeof(dform[0]) - 1); // 减1预留终止符位置
    
  • 编译器栈保护特性(仅用于终止溢出程序)
    如GCC添加-fstack-protector-all编译选项,会在栈帧插入保护字节,溢出时直接终止程序,但无法实现中途修复与执行恢复,仅适合预防场景。


二、溢出后的修复与执行恢复

要实现异常处理式的恢复执行,可通过以下方式:

  • 子程序内截断字符串修复
    检测到溢出后,手动截断字符串至有效长度并补全终止符,随后继续执行原有逻辑:

    void checkdate(char *dform, size_t max_valid_len) {
        size_t actual_len = strlen(dform);
        if (actual_len > max_valid_len) {
            // 截断字符串,保留max_valid_len个字符并添加终止符
            dform[max_valid_len] = '\0';
            printf("已修复溢出:截断后的字符串为%s\n", dform);
        }
        // 继续执行日期验证等原有逻辑...
    }
    
  • 返回错误码由调用方修复
    子程序返回溢出错误码,调用方根据错误码修正字符串后重新调用:

    // 定义错误码
    #define DATE_OVERFLOW 1
    #define DATE_VALID 0
    
    int checkdate(char *dform, size_t max_valid_len) {
        size_t actual_len = strlen(dform);
        if (actual_len > max_valid_len) {
            return DATE_OVERFLOW;
        }
        // 日期验证逻辑...
        return DATE_VALID;
    }
    

    调用方处理:

    char dform[12];
    strcpy(dform, "june-11-2024");
    int ret = checkdate(dform, sizeof(dform)/sizeof(dform[0]) - 1);
    if (ret == DATE_OVERFLOW) {
        // 替换为符合长度要求的字符串
        strncpy(dform, "jun-11-2024", sizeof(dform)-1);
        dform[sizeof(dform)-1] = '\0'; // 确保终止符存在
        // 重新调用子程序
        checkdate(dform, sizeof(dform)/sizeof(dform[0]) - 1);
    }
    

三、根源避免溢出:使用安全字符串函数

优先使用strncpy替代strcpy,从源头避免溢出:

char dform[12];
// 最多写入11个字符,手动补全终止符
strncpy(dform, "june-11-2024", sizeof(dform)-1);
dform[sizeof(dform)-1] = '\0';
checkdate(dform);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:53:18