Warning C26414

"Move, copy, reassign or reset a local smart pointer."

C++ Core Guidelines:
R.5: Prefer scoped objects, don't heap-allocate unnecessarily

Smart pointers are convenient for dynamic resource management, but they're not always necessary. For example, it may be easier and more efficient to manage a local dynamic buffer by using a standard container. You may not need dynamic allocation at all for single objects, for example, if they never outlive their creator function. They can be replaced with local variables. Smart pointers become handy when a scenario requires a change of ownership. For example, when you reassign a dynamic resource multiple times, or in multiple paths. They're also useful for resources obtained from external code. And, when smart pointers are used to extend the lifetime of a resource.

Remarks

This check recognizes both the standard std::unique_pointer and std::shared_pointer templates, and user-defined types that are likely intended to be smart pointers. Such types are expected to define the following operations:

  • overloaded dereference or member access operators that are public and not marked as deleted;

  • a public destructor that isn't deleted or defaulted. That includes destructors explicitly defined as empty.

The type Microsoft::WRL::ComPtr behaves as a shared pointer, but it's often used in specific scenarios that are affected by the COM lifetime management. To avoid excessive noise this type is filtered out.

This check looks for explicit local allocations assigned to smart pointers, to identify if scoped variables could work as an alternative. Both direct calls to operator new, and special functions like std::make_unique and std::make_shared, are interpreted as direct allocations.

Code analysis name: RESET_LOCAL_SMART_PTR

Example

Dynamic buffer:

void unpack_and_send(const frame &f)
{
    auto buffer = std::make_unique<char[]>(f.size()); // C26414
    f.unpack(buffer.get());
    // ...
}

Dynamic buffer replaced by container:

void unpack_and_send(const frame &f)
{
    auto buffer = std::vector<char>(f.size());
    f.unpack(buffer.data());
    // ...
}