C++中使用vector或make_unique获取WCHAR及GetText适配方案
适配现有GetText函数的三种调用方式
1. 原始指针(new/delete)
你的原有代码已经可以正常工作,这里再明确调用逻辑:
auto* sResult = new WCHAR[256]; GetText(&sResult, 256); // 直接传递指针的地址,函数会向指针指向的缓冲区写入内容 delete[] sResult;
2. std::vector
直接取&sResult2.data()会触发问题:data()返回的是临时指针值,并非可修改的左值,取其地址属于未定义行为。正确做法是先把缓冲区指针存入临时变量,再传递变量地址:
std::vector<WCHAR> sResult2(256); WCHAR* vecBuffer = sResult2.data(); GetText(&vecBuffer, sResult2.size()); // 写入操作直接作用于vector的内部缓冲区,无需额外处理
注:你的GetText仅写入已有缓冲区,不会重新分配内存,因此临时指针和vector内部指针指向同一块内存,操作安全。
3. std::unique_ptr<WCHAR[]>
和vector逻辑一致,需要先将get()返回的指针存入临时变量,再传递地址:
auto sResult3 = std::make_unique<WCHAR[]>(256); WCHAR* uniqueBuffer = sResult3.get(); GetText(&uniqueBuffer, 256); // unique_ptr的内存管理不受影响,内容已写入缓冲区
重写GetText使其更易用
现有WCHAR**的参数设计冗余且易出错,可通过重载函数直接适配不同类型,无需额外临时变量:
重载版本1:兼容原始指针
保留对原始指针的支持:
void GetText(WCHAR* sText, DWORD dwTextSize) { StringCchPrintfW(sText, dwTextSize, L"this is a %s", L"test"); }
重载版本2:直接接收std::vector
利用vector的内置大小和缓冲区:
void GetText(std::vector<WCHAR>& buffer) { if (buffer.empty()) return; StringCchPrintfW(buffer.data(), buffer.size(), L"this is a %s", L"test"); }
重载版本3:接收std::unique_ptr<WCHAR[]>
由于unique_ptr数组无法直接获取大小,需传入长度参数:
void GetText(std::unique_ptr<WCHAR[]>& buffer, DWORD dwTextSize) { if (!buffer) return; StringCchPrintfW(buffer.get(), dwTextSize, L"this is a %s", L"test"); }
调用示例
现在可以直接调用,代码更简洁:
int main() { // 原始指针 auto* sResult = new WCHAR[256]; GetText(sResult, 256); delete[] sResult; // vector std::vector<WCHAR> sResult2(256); GetText(sResult2); // unique_ptr auto sResult3 = std::make_unique<WCHAR[]>(256); GetText(sResult3, 256); }
更优雅的优化:返回std::wstring
如果业务场景允许,可让函数直接返回字符串,彻底规避手动内存管理:
#include <string> std::wstring GetText() { std::wstring buffer(256, L'\0'); StringCchPrintfW(buffer.data(), buffer.size(), L"this is a %s", L"test"); buffer.resize(wcslen(buffer.data())); // 裁剪多余的空字符(可选) return buffer; } // 调用示例 std::wstring result = GetText();
这种方式无需关注缓冲区大小,也不会出现内存泄漏风险。
内容的提问来源于stack exchange,提问作者JeffR
相关产品推荐
相关产品推荐

