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

C语言自定义split函数返回结构体int成员乱值、段错误问题排查

C语言自实现split函数size乱值、段错误问题修复

问题根因

从异常日志可直接定位三个核心编码错误:

  • 堆内存越界写入踩坏结构体成员:日志中printf("size: %d", len - 1)输出size: 3lry是典型的内存越界覆盖特征。测试字符串"lryabruahsdfads"中分隔符'a'共出现3次,正常分割后子串总数为4,你给结构体中arr二级指针分配的内存空间仅够存储3个char*类型指针,写入第4个子串指针时直接越界覆盖了相邻内存中存储的size成员值,导致size值被污染为脏数据。
  • 子串处理逻辑遗漏末尾段:日志打印"ds is the last at pos 4"说明遍历原串时索引计算完全错位,遇到最后一个分隔符后没有将末尾剩余的"ds"子串存入结果数组,数组实际存储的有效子串数量和预期值不匹配。
  • 字符串结束符缺失导致越界读:逐字符拼接子串时没有为每个子串预留'\0'结束符的1字节空间,或拼接完成后未手动补写结束符,导致遍历子串时读取到非法内存地址,最终触发段错误。

修复方案

按以下顺序修正代码即可解决问题:

  1. 修正size计算与内存分配逻辑
    无空串跳过逻辑的前提下,分割后子串总数固定为「分隔符总个数 + 1」,给arr分配内存时严格按照sizeof(char*) * 子串总数申请空间,禁止少算字节数。给split_arr结构体、arr数组、每个子串分配内存后必须检查返回值,避免分配失败操作野指针。
  2. 修正子串遍历与拼接逻辑
    逐字符遍历原串时,遇到分隔符则截断当前子串、存入结果数组、重置子串拼接起始索引;遍历到原串末尾的'\0'时,必须将最后一段未处理的子串存入数组,禁止遗漏末尾段。每个子串分配内存时长度固定为「子串字符数 + 1」,最后一字节手动赋值'\0',保证字符串合法。
  3. 修正测试代码遍历逻辑
    遍历结果数组时严格以结构体中存储的size成员值作为循环上限,禁止硬编码len-1这类偏移值访问数组,避免越界。

参考核心实现代码:

split_arr* split(const char* str, char delm) {
    int delm_cnt = count_delm(str, delm);
    int sub_str_cnt = delm_cnt + 1;
    split_arr* res = (split_arr*)malloc(sizeof(split_arr));
    res->arr = (char**)malloc(sizeof(char*) * sub_str_cnt);
    res->size = sub_str_cnt;

    int arr_pos = 0;
    int str_start = 0;
    int i = 0;
    while (1) {
        if (str[i] == delm || str[i] == '\0') {
            int sub_len = i - str_start;
            char* sub_str = (char*)malloc(sub_len + 1);
            strncpy(sub_str, str + str_start, sub_len);
            sub_str[sub_len] = '\0';
            res->arr[arr_pos++] = sub_str;
            str_start = i + 1;
        }
        if (str[i] == '\0') break;
        i++;
    }
    return res;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 14:57:18