Main Content

MISRA C++:2023 Rule 21.6.3

Advanced memory management shall not be used

Since R2024b

Description

Rule Definition

Advanced memory management shall not be used 1

Rationale

Using advanced memory management relies on properly handling complex issues such as object lifetimes and use of std::launder. These complexities can result in difficult issues that are hard to identify and result in undefined behavior.

Examples of advanced memory management functions include:

  • All overloads of operator new and operator delete except for these overloads and their array counterparts:

    • void * operator new (std::size_t count);

    • void * operator new (std::size_t count, const std::nothrow_t & tag);

    • void operator delete (void * ptr) noexcept;

    • void operator delete (void * ptr, std::size_t sz) noexcept;

    • void operator delete (void * ptr, const std::nothrow_t & tag) noexcept;

  • Use of std::launder

  • Functions provided by the header file <memory> including:

    • destroy(), destroy_at(), and destroy_n()

    • uninitialized_copy() and uninitialized_copy_n()

    • uninitialized_move() and uninitialized_move_n()

    • uninitialized_fill() and uninitialized_fill_n()

    • uninitialized_default_construct() and uninitialized_default_construct_n()

    • uninitialized_value_construct() and uninitialized_value_construct_n()

    For a full list of advanced memory management functions and exceptions, see the MISRA™ C++:2023 documentation.

Uses of advanced memory management include:

  • Calling an advanced memory management function directly or by using a new expression or a delete expression

  • Taking the address of an advanced memory management function

  • Explicitly calling a destructor

  • Declaring an operator new or operator delete function

Polyspace Implementation

Polyspace® reports violations on:

  • Declarations or uses of any advanced memory management function

  • Overloads of operator new and operator delete (not including exceptions described in the Rationale section)

  • Explicitly calling a destructor or explicitly declaring an operator new or operator delete function

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include <iostream>
#include <memory>
#include <vector>
#include <string>

int main() {
    std::vector<std::string> source = {"Hello", "World", "C++", "Memory"};
    void* rawMemory = operator new[](source.size() * sizeof(std::string));  // Compliant

    std::string* dest = static_cast<std::string*>(rawMemory);

    try {
        std::uninitialized_copy(source.begin(), source.end(), dest);        // Noncompliant

        for (size_t i = 0; i < source.size(); ++i) {
            std::cout << dest[i] << std::endl;
        }
        std::destroy(dest, dest + source.size());                           // Noncompliant
    } catch (...) {
        operator delete[](rawMemory);
        throw;  
    }

    operator delete[](rawMemory);

    return 0;
}

This example uses std::uninitialized_copy() to create a string object inside rawMemory by copying from the source vector. Use of std::uninitialized_copy() is noncompliant.

While the operator new[]() function is compliant for this rule, it is still a nonautomatic form of memory management and violates MISRA C++:2023 Rule 21.6.2.

#include <new>
#include <iostream>

struct X { int m; };

int main() {
    unsigned char buf[sizeof(X)];
    X* p = new (buf) X{2023};                        // Noncompliant
    p->~X();                                         // Noncompliant
    X* q = new (buf) X{42};                          // Noncompliant
    std::cout << std::launder(q)->m << std::endl;    // Noncompliant
}

In this example, two overloads of operator new occur, which is advanced memory management. The code also explicitly calls a destructor in p->~X();.

Check Information

Group: Language support library
Category: Required

Version History

Introduced in R2024b


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.