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

如何从std::string获取持久char*指针 调用free时不出现堆损坏

问题根因

你出现堆损坏的核心原因是字符串内存分配长度未包含C风格字符串必备的末尾空终止符\0:

  • C标准库的strlen()函数返回的是字符串的有效字符长度,不计算末尾隐含的\0占位
  • 你调用malloc(strlen(xxx)*sizeof(char))时仅分配了有效字符的空间,后续strcpy会额外写入1字节的\0到已分配内存的边界外,直接触发堆溢出损坏

你在释放前能正常打印字符串是因为\0虽然写越界了,但刚好落在堆的未使用保护区里,没有立刻触发异常,直到释放时CRT检查堆完整性才会报损坏错误。

修复方案

方案1:直接修正现有分配逻辑

给每处malloc的长度加1,预留空终止符的位置即可:

ResultItemAttributeClass theAttribute;
char* tmpObtainedValueName = (char*)obtainedValue.Name();
// 长度+1预留\0位置
theAttribute.AttributeName = (char*)malloc((strlen(tmpObtainedValueName) + 1) * sizeof(char));
strcpy(theAttribute.AttributeName, tmpObtainedValueName);

string tmpObtainedValueType0 = obtainedValue.aDesc->TypeName();
char* tmpObtainedValueType = (char*) tmpObtainedValueType0.c_str();
theAttribute.AttributeType = (char*)malloc((strlen(tmpObtainedValueType) + 1) * sizeof(char));
strcpy(theAttribute.AttributeType, tmpObtainedValueType);

string tmpAttributeValue0= obtainedValue.asStr();
char* tmpAttributeValue = (char*) tmpAttributeValue0.c_str();
theAttribute.AttributeValue = (char*)malloc((strlen(tmpAttributeValue) + 1) * sizeof(char));
strcpy(theAttribute.AttributeValue, tmpAttributeValue);

方案2:封装通用安全实现(推荐)

如果要避免重复写分配逻辑,还可以封装专用的std::string转持久化char*函数,同时兼容跨DLL场景:

// 通用转换函数,自动处理内存分配和空终止符
char* StringToPersistentCharPtr(const std::string& src) {
    size_t strLen = src.size();
    char* buf = (char*)malloc(strLen + 1);
    if (buf != nullptr) {
        memcpy(buf, src.c_str(), strLen);
        buf[strLen] = '\0';
    }
    return buf;
}

// 调用时大幅简化代码
theAttribute.AttributeName = StringToPersistentCharPtr(obtainedValue.Name());
theAttribute.AttributeType = StringToPersistentCharPtr(obtainedValue.aDesc->TypeName());
theAttribute.AttributeValue = StringToPersistentCharPtr(obtainedValue.asStr());

额外注意事项

如果修复分配长度后仍然出现内存异常,请确认DLL和调用方使用的CRT运行库版本完全一致(同用动态CRT/同用静态CRT),如果分配操作在DLL的CRT堆执行、释放在调用方的CRT堆执行,也会触发内存错误。

内容的提问来源于stack exchange,提问作者Ivan P.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 15:18:04