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

C++字符串vector转C字符串数组报double free错误求助

解决C++ string向量转C风格字符串数组的内存错误问题

错误根源

代码触发double free or corruption (out):错误的核心原因是内存越界访问:

  • C主函数初始化num_apn=0,调用malloc(num_apn*sizeof(char*))相当于分配0字节内存,arr是无效指针。
  • 在C++函数get_num_apn中直接对arr[i]赋值,属于写入未分配的堆内存,破坏了堆结构,最终导致释放内存时触发错误。

修复方案(单次调用版本)

调整函数参数,让C++函数负责分配存储指针的数组内存,确保内存分配时机和大小正确,同时增加错误处理避免泄漏。

修复后的C++代码

#include <vector>
#include <string>
#include <cstring>
#include <cstdlib>

// 用extern "C"保证C语言能正确调用
extern "C" void get_num_apn(unsigned int *num_apn, char ***arr)
{
    std::vector<std::string> apn = { 
        "ghadz", "internet.ooredoo.tn",  "mms.ooredoo.tn",
        "internet.tn","gprs.tn", "mms.tn", "weborange", "mms.otun" 
    };
    *num_apn = apn.size();
    *arr = nullptr;

    // 分配存储char*指针的数组
    *arr = static_cast<char**>(malloc(*num_apn * sizeof(char*)));
    if (*arr == nullptr) {
        *num_apn = 0;
        return;
    }

    for (unsigned int i = 0; i < apn.size(); ++i) {
        (*arr)[i] = strdup(apn[i].c_str());
        // 检查strdup是否成功,失败则回滚
        if ((*arr)[i] == nullptr) {
            for (unsigned int j = 0; j < i; ++j) {
                free((*arr)[j]);
            }
            free(*arr);
            *arr = nullptr;
            *num_apn = 0;
            return;
        }
    }
}

修复后的C主函数代码

#include <stdio.h>
#include <stdlib.h>

// 声明C++导出的函数
void get_num_apn(unsigned int *num_apn, char ***arr);

int main()
{
    unsigned int num_apn = 0;
    char **arr = NULL;

    // 单次调用获取数据和内存
    get_num_apn(&num_apn, &arr);

    if (arr != NULL && num_apn > 0) {
        // 打印结果
        for (unsigned int i = 0; i < num_apn; ++i) {
            printf("arr[%u]=%s\n", i, arr[i]);
        }

        // 释放内存:先释放每个字符串,再释放指针数组
        for (unsigned int i = 0; i < num_apn; ++i) {
            free(arr[i]);
        }
        free(arr);
    }

    return 0;
}

关键修复点说明

  1. 参数调整:将char **arr改为char ***arr,让C++函数可以直接修改主函数中arr指针的值,分配正确大小的内存。
  2. 内存分配时机:在C++函数中先获取向量长度,再分配对应大小的char*数组,彻底避免越界访问。
  3. 错误处理:检查malloc和strdup的返回值,分配失败时回滚已分配的内存,防止内存泄漏。
  4. 跨语言调用兼容:用extern "C"修饰C函数,避免C名字改编导致C主函数无法找到函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 04:56:30