C++ 编译器警告 C26409 - 避免调用 new 和 delete

C++ compiler waring C26409 - avoid calling new and delete

这是我得到的代码(警告 C26409 避免显式调用 new 和 delete,请改用 std::make_unique (r.11)。)在执行 Visual Studio 2019 代码分析后:

#include <windows.h>
#include <strsafe.h>
int main()
{
    auto *sResult = new WCHAR[256];
    StringCchPrintfW(sResult, 256, L"this is a %s", L"test");
    delete[] sResult;
}

我假设使用 new/delete 而不是 calloc/free,但现在编译器告诉我使用 std::make_unique。我找不到任何关于如何更改我的代码以使其合规的示例。

所以我的问题是:

  1. 如何更改我的代码使其不使用 new/delete

  2. 为什么 我不应该使用 new/delte 而不是 std::make_unique?

该警告有些令人困惑,因为它假设您需要直接分配内存。如果事实并非如此:

#include <windows.h>
#include <strsafe.h>
#include <vector>
int main()
{
    std::vector<WCHAR> sResult(256);
    StringCchPrintfW(sResult.data(), sResult.size(), L"this is a %s", L"test");
}

int main()
{
    WCHAR sResult[256];
    StringCchPrintfW(sResult, 256, L"this is a %s", L"test");
}

想法是在可以(小数据)时使用静态存储以提高效率(无 OS 内存调用),并在必须分配时使用 std::vector 因为大小是在编译时未知或对于堆栈来说太大,让 STL 为您完成工作。 std::make_unique 的用法是当你确实需要直接或间接调用 new 并在 auto-destruct 之后使用它时

TL;DR:了解现代 C++ 内存管理。

下面是如何使用 std::unique_ptr 重写它。请注意,最好使用 std::vector<WCHAR>std::wstring 或在堆栈上分配的数组:

#include <memory>

...

{
    auto sResult = std::make_unique<WCHAR[]>(256);
    StringCchPrintfW(sResult.get(), 256, L"this is a %s", L"test");
} // exiting the scope frees the memory

为什么要这样做(或使用 std::vector 或类似的方法?

它简化了代码,因为你不需要考虑函数是如何退出的;编译器确保资源被释放。否则,您需要确保每条执行路径,包括抛出异常或 return 尽早释放所有资源的路径。该编程技术在 C++ 中称为 RAII (Resource Allocation Is Initialization)


注意:鉴于您分配的内存量较小,您可能希望在堆栈上创建内存。这也应该通过删除任何动态内存分配来消除错误:

WCHAR sResult[256];
StringCchPrintfW(sResult, 256, L"this is a %s", L"test");