如何将GetProfileBinary获取的结果保存到智能指针中
解决方案
第一步:修改类成员变量声明
把原来的裸指针成员替换为数组类型的unique_ptr:
// 替换前 // BYTE *m_pbyImportColumnMappings; // 替换后 std::unique_ptr<BYTE[]> m_pbyImportColumnMappings;
修改后类析构时会自动释放管理的内存,不需要手动编写delete[]释放逻辑。
第二步:适配GetProfileBinary接口修改ReadSettings函数
MFC的GetProfileBinary是C风格接口,要求传入裸指针的地址接收内部分配的内存,我们可以先用临时裸指针承接返回值,再把所有权转移给智能指针,修改后的完整代码如下:
void CImportOCLMAssignmentHistoryDlg::ReadSettings() { UINT uSize = 0; BYTE* pRawMappings = nullptr; // 临时裸指针承接GetProfileBinary的输出 m_dwImportFlags = theApp.GetNumberSetting(theApp.GetActiveScheduleSection(_T("Options")), _T("ImportFlags"), ImportAssignment::None); theApp.GetProfileBinary(theApp.GetActiveScheduleSection(_T("Options")), _T("ImportColumnMappings"), reinterpret_cast<LPBYTE*>(&pRawMappings), &uSize); // 把返回的内存所有权转移给智能指针,自动管理生命周期 m_pbyImportColumnMappings.reset(pRawMappings); // Reset memory buffer (if required) if (uSize != (sizeof(BYTE) * 15)) { // 不需要手动delete,reset会自动释放原有内存 m_pbyImportColumnMappings.reset(new BYTE[15]); // 填充默认值,gsl::span用法不变 const gsl::span column_mappings(m_pbyImportColumnMappings.get(), 15); std::fill(begin(column_mappings), end(column_mappings), -1); } }
关键逻辑说明
GetProfileBinary内部分配的内存是用new[]分配的,刚好匹配std::unique_ptr<BYTE[]>的默认删除器,不会出现内存释放不匹配的问题- 用临时裸指针承接输出是因为
unique_ptr::get()返回的是指针右值,无法直接取地址传入接口要求的LPBYTE*参数 - 调用
reset方法的时候,智能指针会自动释放之前持有的内存,不需要手动判断非空再delete
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

