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

521 views Asked by At

Here is my code that I'm getting (Warning C26409 Avoid calling new and delete explicitly, use std::make_unique instead (r.11).) after doing a Visual Studio 2019 Code Analysis:

#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;
}

I was under the assumption to use new/delete instead of calloc/free, but now the compiler is telling me to use std::make_unique. I can't find any examples on how I can change my code to be compliant.

So my questions are:

  1. how do I change my code so it doens't use new/delete

  2. why should I not use new/delte vs std::make_unique?

2

There are 2 answers

3
fabian On BEST ANSWER

Here's how you could rewrite this using std::unique_ptr. Note that the use of std::vector<WCHAR>, std::wstring or an array allocated on the stack would be preferable:

#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

Why should you do this (or use std::vector or similar?

It simplifies the code, since you don't need to think about how the function is exited; the compiler ensures the resources are freed. Otherwise you need to make sure for every execution path including ones that throw an exception or return early free all resources. The programming technique is called RAII (Resource Allocation Is Initialization) in C++.


Note: Given the small amount of memory you allocate, you may want to create the memory on the stack though. This should also get rid of the error by removing any dynamic memory allocations:

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

The warning is somewhat confusing, because it assumes that you need some direct memory allocation. If fact, you don't:

#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");
}

or

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

The idea is to use static storage when you can (small data) to be more efficient (no OS memory call), and use std::vector when you must allocate because the size is either unknown at compile time or too big for the stack and let STL do the work for you. The usage of std::make_unique is when you indeed need to call new directly or indirectly and have it auto-destruct later.

TL;DR: Read about modern C++ memory management.