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

isl库方法引发std::bad_alloc内存分配失败问题排查求助

问题:使用ISL库构建约束映射时触发std::bad_alloc异常

在实现统计迭代器名称及其约束数量的函数时,调用ISL库接口构建std::unordered_map过程中触发std::bad_alloc内存分配异常,已尝试调用ISL专用释放函数(如isl_constraint_free、isl_basic_set_free等)但问题未解决。相关代码如下:

std::unordered_map<std::string, int> utility::get_constraints_map(isl_set *set)
{
    isl_basic_set_list *bset_list = isl_set_get_basic_set_list(set);
    std::unordered_map<std::string, int> constraints_map{};
    
    int n_basic_set = isl_set_n_basic_set(set);
    for (int i = 0; i < n_basic_set; i++)
    {
        isl_basic_set *bset = isl_basic_set_list_get_basic_set(bset_list, i);
        isl_constraint_list *cst_list = isl_basic_set_get_constraint_list(bset);
        for (int j = 0; j < isl_constraint_list_n_constraint(cst_list); j++)
        {
            isl_constraint *cst = isl_constraint_list_get_constraint(cst_list, j);
    
            for (int k = 0; k < isl_set_dim(set, isl_dim_out); k++)
            {
                std::string dim_name = isl_set_get_dim_name(set, isl_dim_out, k);
            
                if (isl_constraint_involves_dims(cst, isl_dim_set, k, 1))
                {
                    if (constraints_map.find(dim_name) != constraints_map.end())
                    {
                        constraints_map.at(dim_name) = constraints_map[dim_name] + 1;
                    }
                    else
                    {
                        constraints_map.insert({dim_name, 0});
                    }
                    break;
                }
            }
        }
    }
    return constraints_map;
}

核心问题分析

std::bad_alloc通常由内存耗尽引发,结合ISL库的内存管理规则,问题根源是ISL临时对象未被正确释放,导致内存泄漏累积。ISL采用引用计数管理对象生命周期,所有通过get系列函数获取的子对象(如isl_basic_set、isl_constraint等)都需要手动调用对应free函数释放,否则会持续占用内存,最终耗尽系统内存触发分配异常。

原代码中所有获取的ISL临时对象(bset_list、bset、cst_list、cst)均未释放,即使尝试过释放,也可能存在释放时机错误或遗漏的情况。

修复方案

1. 严格释放所有ISL临时对象

在每个临时对象使用完毕后,立即调用对应释放函数,确保内存及时回收:

  • isl_basic_set_list使用后调用isl_basic_set_list_free
  • 每个循环内的isl_basic_set调用isl_basic_set_free
  • 每个循环内的isl_constraint_list调用isl_constraint_list_free
  • 每个循环内的isl_constraint调用isl_constraint_free

2. 优化映射操作逻辑

原代码中find+insert/at的写法可简化为operator[],既减少重复查找开销,也避免逻辑冗余:当键不存在时operator[]会自动插入默认值(0),直接累加即可。

修复后的代码

std::unordered_map<std::string, int> utility::get_constraints_map(isl_set *set)
{
    if (!set) {
        return {};
    }

    isl_basic_set_list *bset_list = isl_set_get_basic_set_list(set);
    std::unordered_map<std::string, int> constraints_map{};
    
    int n_basic_set = isl_set_n_basic_set(set);
    for (int i = 0; i < n_basic_set; i++)
    {
        isl_basic_set *bset = isl_basic_set_list_get_basic_set(bset_list, i);
        isl_constraint_list *cst_list = isl_basic_set_get_constraint_list(bset);
        
        int n_constraints = isl_constraint_list_n_constraint(cst_list);
        for (int j = 0; j < n_constraints; j++)
        {
            isl_constraint *cst = isl_constraint_list_get_constraint(cst_list, j);
    
            int out_dim_count = isl_set_dim(set, isl_dim_out);
            for (int k = 0; k < out_dim_count; k++)
            {
                const char *dim_name_c = isl_set_get_dim_name(set, isl_dim_out, k);
                if (!dim_name_c) {
                    continue;
                }
                std::string dim_name(dim_name_c);
            
                if (isl_constraint_involves_dims(cst, isl_dim_set, k, 1))
                {
                    // 用operator[]简化逻辑:不存在则插入0,存在则直接累加
                    constraints_map[dim_name]++;
                    break;
                }
            }
            
            isl_constraint_free(cst); // 释放当前约束对象
        }
        
        isl_constraint_list_free(cst_list); // 释放约束列表
        isl_basic_set_free(bset); // 释放基本集合对象
    }
    
    isl_basic_set_list_free(bset_list); // 释放基本集合列表
    return constraints_map;
}

额外检查点

  • 确认传入的isl_set *set是有效对象,未被提前释放或置空,无效的set会导致ISL函数返回异常对象,引发未定义行为。
  • 如果处理的集合规模极大,可考虑提前预留unordered_map的空间(如reserve),减少动态分配次数,但这不是触发bad_alloc的核心原因。

内容的提问来源于stack exchange,提问作者Zidane Zine eddine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:10:48