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; }
关键修复点说明
- 参数调整:将
char **arr改为char ***arr,让C++函数可以直接修改主函数中arr指针的值,分配正确大小的内存。 - 内存分配时机:在C++函数中先获取向量长度,再分配对应大小的
char*数组,彻底避免越界访问。 - 错误处理:检查
malloc和strdup的返回值,分配失败时回滚已分配的内存,防止内存泄漏。 - 跨语言调用兼容:用
extern "C"修饰C函数,避免C名字改编导致C主函数无法找到函数。
内容的提问来源于stack exchange,提问作者sarra
相关产品推荐
相关产品推荐

