Main Content

MISRA C++:2023 Rule 21.6.1

Dynamic memory should not be used

Since R2024b

Description

Rule Definition

Dynamic memory should not be used

Rationale

Use of dynamic memory can result in safety issues such as memory leaks, resource exhaustion, and nondeterministic execution times. A program can explicitly or implicitly use dynamic memory, and avoiding use of dynamic memory can be difficult. Few programs can completely avoid the use of dynamic memory.

If you must use dynamic memory, provide justifications and supporting documentation for how any potential issues are managed in your project.

To minimize memory management defects, software design should establish clear policies for managing the lifetime of allocated memory. For example:

  • Clearly define which parts of the software are responsible for allocated memory so that every piece of allocated memory has a known owner responsible for its lifecycle.

  • Prefer simple ownership models, such as unique ownership (std::unique_ptr), over more complex shared ownership models. Simple ownership models are easier to understand and reduce the risk of errors.

  • Be cautious with reference counting mechanisms such as std::shared_ptr for managing lifetimes because they can lead to memory leaks due to circular references. Design relationships to avoid such scenarios or use weak pointers (std::weak_ptr) to break potential cycles.

  • Limit the execution of dynamic memory, such as allocation or deallocation functions, to nonessential phases of the program's lifecycle. For example, enabling these calls during the initialization phase and filling the allocated memory right away can identify memory exhaustion issues at the moment of allocation.

Polyspace Implementation

Polyspace® reports violations on these uses of dynamic memory.

  • Objects with dynamic storage operation managed with operator new or operator delete.

  • The functions calloc, malloc, realloc, aligned_alloc, and free.

  • Platform specific memory allocation or deallocation functions.

    .

  • Implicit uses of dynamic memory. For example, when you instantiate a container without explicitly specifying an allocator, std::allocator is used by default.

    #include <vector>
    #include <memory>
    
    int main() {
        std::vector<int> myVector; // Noncompliant
                                   // Uses std::allocator<int> implicitly
    }

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 <cstdlib>
#include <iostream>

class MyClass {
public:
    MyClass() { std::cout << "Constructor called\n"; }
    ~MyClass() { std::cout << "Destructor called\n"; }
};

int exampleClass() {
    MyClass* myObject = new MyClass();     // Noncompliant
    delete myObject;                       // Noncompliant
}

int main() {
	exampleClass();
    int* arr = static_cast<int*>(std::malloc(5 * sizeof(int)));    // Noncompliant
    int* arr_c = static_cast<int*>(std::calloc(5, sizeof(int)));   // Noncompliant
    std::free(arr);                                                // Noncompliant
    std::free(arr_c);                                              // Noncompliant
}

In this example:

  • The dynamic allocation and deallocation of memory for the object MyClass using the new and delete operators is noncompliant.

  • Use of malloc, calloc, and free are noncompliant.

Check Information

Group: Language support library
Category: Advisory

Version History

Introduced in R2024b