Pour obtenir une clé
d'essai remplissez le formulaire ci-dessous
Demandez des tariffs
Nouvelle licence
Renouvellement de licence
--Sélectionnez la devise--
USD
EUR
RUB
* En cliquant sur ce bouton, vous acceptez notre politique de confidentialité

Free PVS-Studio license for Microsoft MVP specialists
To get the licence for your open-source project, please fill out this form
** En cliquant sur ce bouton, vous acceptez notre politique de confidentialité.

I am interested to try it on the platforms:
** En cliquant sur ce bouton, vous acceptez notre politique de confidentialité.

Votre message a été envoyé.

Nous vous répondrons à


Si vous n'avez toujours pas reçu de réponse, vérifiez votre dossier
Spam/Junk et cliquez sur le bouton "Not Spam".
De cette façon, vous ne manquerez la réponse de notre équipe.

>
>
>
V824. It is recommended to use the 'mak…
Analyzer diagnostics
General Analysis (C++)
General Analysis (C#)
General Analysis (Java)
Diagnosis of micro-optimizations (C++)
Diagnosis of 64-bit errors (Viva64, C++)
Customer specific requests (C++)
MISRA errors
AUTOSAR errors
OWASP errors (C#)
Problems related to code analyzer
Additional information
Contents

V824. It is recommended to use the 'make_unique/make_shared' function to create smart pointers.

02 Jui 2020

The analyzer recommends that you create a smart pointer by calling the 'make_unique' / 'make_shared' function rather than by calling a constructor accepting a raw pointer to the resource as a parameter.

Using these functions has the following advantages:

  • the code is made clearer by removing explicit calls of the 'new' operator for dynamic allocations (smart pointers in themselves remove explicit calls of the 'delete' operator);
  • better security in case of exception;
  • optimized object allocation.

Consider the following example:

void foo(std::unique_ptr<int> a, std::unique_ptr<int> b)
{
  ....
}

void bar()
{
  foo( std::unique_ptr<int> { new int { 0 } },
       std::unique_ptr<int> { new int { 1 } });
}

Since the standard does not define a evaluation order of function arguments, the compiler may choose the following order for the sake of optimization:

  • Call 'new int { 0 }'
  • Call 'new int { 1 }'
  • The first call of the 'std::unique_ptr<int>' constructor
  • The second call of the 'std::unique_ptr<int>' constructor

Now, if the second call of 'new' throws an exception, a memory leak will occur as the resource allocated by the first call of 'new' will never be freed. Using the 'make_unique' function to create the pointer helps solve this problem by guaranteeing the freeing of memory if an exception occurs.

Optimized version:

void foo(std::unique_ptr<int> a, std::unique_ptr<int> b)
{
  ....
}

void bar()
{
  foo( std::make_unique<int>(0), std::make_unique<int>(1));
}

The C++17 standard, while still not specifying the exact evaluation order for arguments, provides additional guarantees. All side effects of a function argument must be evaluated before the next argument is evaluated. This helps mitigate the risk in case of exceptions, but it is still preferable to use 'make_unique'.

One thing should be noted about the 'make_shared' function. When it is used, the pointer's control block is allocated next to the managed object. This helps reduce the number of dynamic allocations and optimize the use of the CPU cache.

The object gets deleted when the reference counter reaches zero, but the control block exists as long as there are existing weak references to the pointer. If both the control block and the managed object were created using the 'make_shared' function (i.e. allocated in the same memory block), the program will not be able to deallocate that memory as long as the reference counter is at zero and there is at least one 'weak_ptr' to the object. This may be unwanted behavior with large objects. If you intentionally avoid using the 'make_shared' function to avoid having both the control block and the object getting allocated in the same memory block, you can suppress the warning.

There is a restriction concerning the use of different versions of the C++ standard: as the functionality of 'make_unique' and 'make_shared' has changed several times since C++11, the diagnostic's behavior depends on the standard's version as follows:

  • C++11: the analyzer suggests replacing object allocation and subsequent passing to the 'shared_ptr' constructor with the 'make_shared' function.
  • C++14 or higher: the analyzer additionally suggests replacing allocation of a single object or array of objects with the 'make_unique' function.
  • C++20 or higher: the analyzer additionally suggests replacing the 'shared_ptr' constructor with the 'make_shared' function for arrays of objects as well.

Unicorn with delicious cookie
Nous utilisons des cookies pour améliorer votre expérience de navigation. En savoir plus
Accepter