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

释放regex_t数组结构体时遇SEGV错误与内存泄漏问题求助

问题分析与解决方案

核心问题

代码崩溃的根本原因是对regex_t结构体进行了浅拷贝,导致多个regex_t实例共享同一块内部动态内存,最终触发重复释放(Double Free)或访问已释放内存的错误:

  1. add_pat函数中直接赋值regex_t结构体:patterns->elem[num] = new_pat;,而regex_t内部包含动态分配的正则表达式数据,直接拷贝会让两个实例共享同一块内存。
  2. 最小复现代码中重复使用同一个new_reg变量两次调用regcomp,且未在中间调用regfree,属于未定义行为,会导致内存泄漏或内部数据混乱。
  3. 开启regfree循环时,数组元素和main中的new_reg会重复释放同一块内存,触发SEGV错误;注释循环时,数组内regex_t的内部内存未被释放,导致内存泄漏。

修复方案

方案1:在数组元素上直接编译正则(推荐)

避免传递已编译好的regex_t,改为传递模式字符串和编译标志,在add_pat内部为新元素编译正则,确保每个实例独立:

reg_arr* add_pat(reg_arr* patterns, const char* pattern, int I_flag, int* flag) {
    int num = patterns->num;
    regex_t* temp = realloc(patterns->elem, (num + 1) * sizeof(regex_t));
    if (temp) {
        patterns->elem = temp;
        // 直接在新数组元素上编译正则
        int res = I_flag ? regcomp(&patterns->elem[num], pattern, REG_ICASE) 
                        : regcomp(&patterns->elem[num], pattern, 0);
        if (res == 0) {
            patterns->num = num + 1;
        } else {
            // 编译失败,回滚内存分配
            free(temp);
            *flag = 0;
        }
    } else {
        *flag = 0;
    }
    return patterns;
}

调整main调用逻辑:

int check = 1;
reg_arr* pats = init_regex(&check);
if (check) pats = add_pat(pats, "word", 0, &check);
if (check) pats = add_pat(pats, "int", 0, &check);
free_reg(pats);

方案2:使用regdup复制正则实例(平台依赖)

部分POSIX系统提供regdup函数,可复制已编译的regex_t生成独立副本:

reg_arr* add_pat(reg_arr* patterns, const regex_t* new_pat, int* flag) {
    int num = patterns->num;
    regex_t* temp = realloc(patterns->elem, (num + 1) * sizeof(regex_t));
    if (temp) {
        patterns->elem = temp;
        // 复制正则实例
        if (regdup(&patterns->elem[num], new_pat) == 0) {
            patterns->num = num + 1;
        } else {
            free(temp);
            *flag = 0;
        }
    } else {
        *flag = 0;
    }
    return patterns;
}

注意:regdup并非所有平台都支持,需确认编译环境是否提供该函数。

修复free_reg函数

无论采用哪种方案,都需要正确释放每个regex_t的内部内存:

void free_reg(reg_arr *reg) {
    if (reg) {
        for (int i = 0; i < reg->num; i++) {
            regfree(&reg->elem[i]);
        }
        free(reg->elem);
        free(reg);
    } 
}

额外注意事项

  • 禁止重复使用同一个regex_t变量调用regcomp而不先调用regfree,这会导致内存泄漏和未定义行为。
  • 确保所有动态分配的内存(包括regex_t内部内存)都被正确释放,避免泄漏或重复释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:01:02