首页 > 解决方案 > 将 std::make_unique 与 GetProfileBinary 函数调用一起使用

问题描述

我已经看到了这个答案(使用 std::make_unique 优于 new 运算符的优点),其中指出:

make_unique如果您需要自定义删除器或从其他地方采用原始指针,请不要使用。

这是我的代码:

void CAutomaticBackupSettingsPage::GetLastBackupDate(COleDateTime& rBackupDate)
{
    DATE* pDatTime = nullptr;
    UINT uSize;

    theApp.GetProfileBinary(_T("Options"), _T("BackupLastBackupDate"), pointer_cast<LPBYTE*>(&pDatTime), &uSize);
    if (uSize == sizeof(DATE))
        rBackupDate = *pDatTime;
    else
        rBackupDate = COleDateTime::GetCurrentTime();

    delete[] pDatTime;
    pDatTime = nullptr;
}

代码分析给了我两个警告:

在此处输入图像描述

在此处输入图像描述

后一个警告建议我使用std::make_unique,但是由于我的指针数据是从GetProfileBinary调用中返回的,并且给出了相关问题中的陈述,这是否意味着我不应该使用std::make_unique?我承认这是我以前没有做过的事情。


使用GetProfileBinary明确指出:

GetProfileBinary分配一个缓冲区并返回它的地址*ppData调用者负责使用释放缓冲区delete[]

标签: c++visual-c++mfccode-analysis

解决方案


pDateTime应该是nullptr,并GetProfileBinary处理分配。代码分析错误地认为你忘记了分配。

它确实需要在调用之前检查是否成功delete[]。我们不能使用delete[]pDatTime,因为pDatTime不是数组。但是GetProfileBinary分配 using new BYTE[size],所以我们需要转换回BYTE.

您还可以NULL在阅读之前添加检查pDatTime,这可能会使代码分析感到高兴。

if (pDatTime && uSize == sizeof(DATE))
    rBackupDate = *pDatTime;
else
    rBackupDate = COleDateTime::GetCurrentTime();
if(pDatTime) delete[](BYTE*)pDatTime;

您可以std::unique_ptr<BYTE[]> cleanup((BYTE*)pDatTime)用于删除,但这必须在GetProfileBinary调用之后。

例子:

DATE* pDatTime = nullptr;
GetProfileBinary(_T("Options"), _T("BackupLastBackupDate"), (LPBYTE*)(&pDatTime), &uSize);
std::unique_ptr<BYTE[]> cleanup((BYTE*)pDatTime); //automatic delete

if (pDatTime && uSize == sizeof(DATE))
    rBackupDate = *pDatTime;
else
    rBackupDate = COleDateTime::GetCurrentTime();

//pDatTime = NULL; <- Error when used with unique_ptr
...
//pDatTime is deleted later, when `cleanup` goes out of scope

推荐阅读