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

C++实现char*转wchar_t*且无内存泄漏的可靠方案咨询

最优实现方案

方案1:返回std::wstring(最推荐)

优先用标准库容器管理内存,完全避免内存泄漏和野指针问题,天然支持任意长度的输入字符串,无需手动干预资源释放:

#include <string>
#include <cstring>
#include <stdlib.h>

std::wstring ConvertToWString(const char* str)
{
    if (str == nullptr) return L"";
    // 预计算转换需要的宽字符总数量(包含结束符)
    size_t requiredSize = 0;
    mbstowcs_s(&requiredSize, nullptr, 0, str, _TRUNCATE);
    if (requiredSize == 0) return L"";
    
    std::wstring wstr(requiredSize - 1, L'\0'); // requiredSize包含结束符,实际有效字符少1位
    size_t convertedCnt = 0;
    mbstowcs_s(&convertedCnt, wstr.data(), requiredSize, str, _TRUNCATE);
    return wstr;
}

调用时直接用std::wstring接收返回值即可,变量离开作用域后会自动释放内存。

注意:你原有的实现直接使用strlen(str)+1作为宽字符缓冲区长度存在隐患,当输入是多字节编码(比如UTF-8)时,字节数不等于宽字符数,可能导致缓冲区不足出现截断,推荐先调用mbstowcs_s预计算所需的宽字符长度。


方案2:必须返回原生wchar_t*的场景

如果上层逻辑强依赖原生指针,有两种安全实现可选:

2.1 约定调用者手动释放

在函数注释中明确内存释放规则,要求调用者用完后主动执行delete[]释放内存:

/**
 * @brief 转换char*为wchar_t*
 * @note 调用者必须在使用完返回值后执行 delete[] 释放内存,否则会出现内存泄漏
 */
wchar_t* ConvertToWString(const char* str)
{
    if (str == nullptr) return nullptr;
    size_t requiredSize = 0;
    mbstowcs_s(&requiredSize, nullptr, 0, str, _TRUNCATE);
    if (requiredSize == 0) return nullptr;
    
    wchar_t* wstr = new wchar_t[requiredSize];
    size_t convertedCnt = 0;
    mbstowcs_s(&convertedCnt, wstr, requiredSize, str, _TRUNCATE);
    return wstr;
}

调用示例:

wchar_t* wstr = ConvertToWString("测试字符串");
// 业务逻辑使用wstr
delete[] wstr; // 必须手动释放内存

2.2 返回智能指针(自动释放)

用std::unique_ptr<wchar_t[]>包装原生指针,离开作用域后自动释放内存,不需要手动管理:

#include <memory>

std::unique_ptr<wchar_t[]> ConvertToWString(const char* str)
{
    if (str == nullptr) return nullptr;
    size_t requiredSize = 0;
    mbstowcs_s(&requiredSize, nullptr, 0, str, _TRUNCATE);
    if (requiredSize == 0) return nullptr;
    
    auto wstr = std::make_unique<wchar_t[]>(requiredSize);
    size_t convertedCnt = 0;
    mbstowcs_s(&convertedCnt, wstr.get(), requiredSize, str, _TRUNCATE);
    return wstr;
}

调用示例:

auto wstr = ConvertToWString("测试字符串");
// 调用wstr.get()即可获取原生指针使用,无需手动释放

原有实现的问题说明
  • 第一个实现的内存泄漏根源是内存所有权不清晰,函数内申请的动态内存没有明确的释放规则,很容易被调用者忽略导致泄漏。
  • 第二个临时方案属于严重的未定义行为:你返回了栈上分配的数组地址,函数执行结束后栈空间会被系统回收,后续访问这个地址的内容完全不可控,只是当前测试场景下没有触发崩溃而已,在复杂逻辑下必然会出现乱码、程序崩溃等问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:15:04