在 GetProfileBinary 函数调用中使用 std::make_unique

Using std::make_unique with the GetProfileBinary function call

我看过这个答案 (),其中指出:

Don't use make_unique if you need a custom deleter or are adopting a raw pointer from elsewhere.

这是我的代码:

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 allocates a buffer and returns its address in *ppData. The caller is responsible for freeing the buffer using delete[].

pDateTime 应该是 nullptrGetProfileBinary 处理分配。代码分析误认为你忘记配置了

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

您还可以在阅读 pDatTime 之前添加一个 NULL 检查,这可能会让代码分析变得愉快。

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