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

C++开发OBS插件DLL时vector.clear后第二次push_back崩溃求助

问题根因

  • 核心原因:Ort::Session::GetInputName/GetOutputName返回的C字符串由传入的ort_alloc分配,调用方负责释放对应的内存。你直接将返回的裸指针存入std::vector<const char*>后,clear()操作仅会清空vector的元素计数,不会释放这些ORT分配的内存,多次调用后产生的堆损坏破坏了vector的内部元数据,最终导致第二次push_back时崩溃。
  • 次要可能原因:你的OBS插件编译使用的C++运行时库,和链接的ONNX Runtime库的编译运行时不匹配(比如插件用/MD动态运行时,却链接了/MT静态运行时编译的ORT库),两个模块使用隔离的堆,跨堆内存操作触发堆损坏。

解决方案

1. 每次更新向量前释放原有字符串

每次调用clear()前,遍历向量使用ort_alloc释放所有已存储的字符串:

static void createSession(struct filter* tf) {
    Ort::SessionOptions sessionOptions;
   
    // 释放之前分配的输入名内存
    for (const char* name : tf->input_names) {
        // 若ort_alloc是C++ API的Allocator实例,使用以下写法
        ort_alloc.Free(const_cast<void*>(reinterpret_cast<const void*>(name)));
        // 若ort_alloc是C API的OrtAllocator*指针,替换为:
        // ort_alloc->Free(ort_alloc, const_cast<char*>(name));
    }
    tf->input_names.clear();
    // 释放之前分配的输出名内存
    for (const char* name : tf->output_names) {
        ort_alloc.Free(const_cast<void*>(reinterpret_cast<const void*>(name)));
        // 对应C API写法:
        // ort_alloc->Free(ort_alloc, const_cast<char*>(name));
    }
    tf->output_names.clear();

    tf->input_names.push_back(tf->session->GetInputName(0, ort_alloc));
    tf->output_names.push_back(tf->session->GetOutputName(0, ort_alloc));
}

2. 校验运行时匹配

检查编译选项一致性:

  • 插件项目属性→C/C++→代码生成→运行库的配置,必须和你链接的ONNX Runtime库的编译配置完全一致,/MD与/MT不能混用,Debug与Release版本不能混用。

3. 额外校验点

  • 确保全局Ort::Env实例的生命周期长于所有Ort::Session实例,不要在Session使用过程中提前销毁Env。
  • 确认第二次调用createSession时,tf->session指向的实例处于有效未销毁状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:06:04