Explicit Memory Management

Explicit memory management has in C++ a high complexity but also provides great functionality. Sadly, this special domain is not so known in C++. For example, you can directly create objects in static memory, in a reserved area, or even a memory pool. That is functionality, which is often key in safety-critical applications in the embedded world. Before the harvest is the work, therefore, I will give in this post an overview, before I dive deeper into the details.

 

In C++, we use new and new[] for memory allocation and delete and delete[] for memory deallocation. But that is by far not the whole story.

Memory allocation

new

Thanks to the operator new, you can dynamically allocate memory for the instance of a type.

int* i= new int;
double* x= new double(10.0);
Circle* c= new Circle;
Point* p= new Point(1.0, 2.0);

 

The in parentheses used arguments are the arguments for the constructor. The result of the new call is a pointer to the according to type. The initialization of the instance is happing after the allocation of the memory. Placement new uses the fact that new consists of two steps. If the object is an object of a class hierarchy, the constructors of all base classes will automatically be performed.

new[]

new[] creates in opposite to new a C array of objects. The newly created objects need a default constructor.

 

Rainer D 6 P2 500x500Modernes C++ Mentoring

  • "Fundamentals for C++ Professionals" (open)
  • "Design Patterns and Architectural Patterns with C++" (open)
  • "C++20: Get the Details" (open)
  • "Concurrency with Modern C++" (open)
  • "Generic Programming (Templates) with C++": October 2024
  • "Embedded Programming with Modern C++": October 2024
  • "Clean Code: Best Practices for Modern C++": March 2025
  • Do you want to stay informed: Subscribe.

     

    double* da= new double[5];
    Circle* ca= new Circle[8];
    

    Placement new

    Placement new is often used to instantiate an object in a pre-reserved memory area. In addition, you can overload placement new globally and for your own data types. This is a big benefit that C++ offers.

    1
    2
    3
    4
    5
    char* memory= new char[sizeof(Account)];
    Account* a= new(memory) Account;
    
    char* memory2= new char[5*sizeof(Account)];
    Account* b= new(memory2) Account[5];
    

     

    Placement new needs an additional argument (lines 2 and 5). Lines 1 and 4 are why the operator new(sizeof(Account),memory) can be used. Or to say it the other way around. The object will be instantiated in the memory area memory. Accordingly, the same holds for the C array b.

    Failed allocation

    If the memory allocations fail new and new[] will raise a std::bad_alloc exception. But that is often not the behavior you want. Therefore, you can invoke placement new with a constant std::nothrow: char* c new(std::nothrow) char[10]. This call causes you will get a nullptr in the error case.

    New handler

    In the case of a failed allocation, you can use std::set_new_handler as your own handler. std::set_new_handler returns the older handler and needs a callable unit. This callable unit should take no argument and return nothing. You can get the currently used handler by invoking the function std::get_new_handler.

    Your handler allows you to implement special strategies for failed allocations:

    • request more memory
    • terminate the program with std::terminate
    • throw an exception of type std::bad_alloc

    Memory deallocation

    delete

    A with new previously allocated memory will be deallocated with delete.

    Circle* c= new Circle;
    ...
    delete c;
    

     

    The object’s destructors and base classes’ destructors will automatically be called. If the base class’s destructor is virtual, you can destroy the object with a pointer or reference to the base class.

    After the object’s memory is deallocated, access to the object is undefined. You can point the pointer of the object to a different object.

    delete[]

    You have to use the operator delete[] to deallocate a C array that was allocated with new[].

    Circle* ca= new Circle[8];
    ...
    delete[] ca;
    

     

    By invoking delete[] all destructors of the objects will automatically be invoked.

    The deallocation of a C array with delete is undefined behavior.

    Placement delete

    According to placement new, you can implement placement delete. But, remarkably, the C++ runtime will not automatically call placement delete. Therefore, it’s the programmer’s duty.

    A typically used strategy invokes the destructor in the first step and placement delete in the second step.  The destructor deinitializes the object, and placement new deallocates the memory.

    char* memory= new char[sizeof(Account)];
    Account* a= new(memory) Account;  // placement new
    ...
    a->~Account();                    // destructor
    operator delete(a,memory);        // placement delete
    
    

    Of course, according to statements and strategies, the usage of placement delete for C arrays holds.

    What’s next?

    The plan is crystal clear. In the next post, I will dig deeper into the overloading of operator new and delete.

     

     

     

     

     

     

     

     

    Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Stephen Kelley, Kyle Dean, Tusar Palauri, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Rob North, Bhavith C Achar, Marco Parri Empoli, Philipp Lenk, Charles-Jianye Chen, Keith Jeffery,and Matt Godbolt.

    Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, Slavko Radman, and David Poole.

    My special thanks to Embarcadero
    My special thanks to PVS-Studio
    My special thanks to Tipi.build 
    My special thanks to Take Up Code
    My special thanks to SHAVEDYAKS

    Modernes C++ GmbH

    Modernes C++ Mentoring (English)

    Do you want to stay informed about my mentoring programs? Subscribe Here

    Rainer Grimm
    Yalovastraße 20
    72108 Rottenburg

    Mobil: +49 176 5506 5086
    Mail: schulung@ModernesCpp.de
    Mentoring: www.ModernesCpp.org

    Modernes C++ Mentoring,

     

     

    0 replies

    Leave a Reply

    Want to join the discussion?
    Feel free to contribute!

    Leave a Reply

    Your email address will not be published. Required fields are marked *