Careful Handling of Resources
The careful handling of resources – may it be, for example, memory, files, or sockets – is a key concern of programming in C++. This holds, in particular, true for embedded programming, which is often characterized by limited resources. Therefore, I will write a few posts about this challenging and versatile topic.
In my first attempt to write this post, I wanted to jump directly into the memory allocation with operator new. Fortunately, I went a few steps back. Memory management is only one but admittedly an important component of resource management in C++. The story is a lot more versatile. So I want to write about three domains of resource management in C++.
There is automatic memory management in C++ that is relatively easy to use. In addition, we have the well-known idioms in C++ that are the base of automatic memory management. At last, C++ offers explicit memory management in which the user has full power. I will follow these three steps in my post because I don’t want to create the impression that explicit memory management is basic knowledge for the C++ developer.
Automatic memory management
I start at the basic level with smart pointers.
Smart pointer
C++ has four different smart pointers. Each of them has the task of taking care of the lifetime of its underlying resource. The std::unique_ptr takes ownership of the lifetime of one resource explicitly. A std::shared_ptr shares the ownership of a resource with the other std::shared_ptr‘s. Therefore, cycles can appear and the resource can not automatically be released. It’s the job of the std::weak_ptr to break these cycles. The last one is the with C++11 deprecated std::auto_ptr. Why? You will see it in a later post.
STL container
STL container cont like std::vector or std::string automatically manages their memory. E.g., they have a method cont.push_back to add a new element to the container. The size of the container will automatically grow. But it also works the other way around. Thanks to cont.shrink_to_fit, the container will be reduced to its size.
Modernes C++ Mentoring
Do you want to stay informed: Subscribe.
C++ idioms
Each modern STL implementation uses the C++ idioms to move semantic, perfect forwarding, and the RAII idiom very often. To understand the underlying mechanism, we must dig deeper into automatic memory management details. Before I write about the C++ idioms, here is a small appetizer.
Move semantic
The critical idea of move semantics is simple: use cheap move operations instead of expensive copy operations for big objects. This holds, in particular, true for such objects that can not be copied. A typical example is a std::mutex or a std::unique_ptr.
Perfect forwarding
Perfect forwarding uses under-the-hood similar techniques like the move semantic. The key idea of perfect forwarding is a different one. The job of perfect forwarding is to take arguments in a function template and forward them identically. The typical use case is constructors that forward their argument to the base class constructor or factory methods that create new objects.
RAII idiom
The idea of the RAII idiom is quite simple. You bind a resource’s acquisition and release to the lifetime of a local object. Therefore, the resource will automatically be initialized in the constructor and released in the destructor. The acronym RAII stands for Resource Acquisition Is Initialization. Smart pointers and locks implement this technique.
Explicit memory management
Now we are in the domain of the experts. Thanks to the explicit memory management in C++, it is possible the tailor memory management to your needs. You can adjust it to simple objects or arrays, but you can also adjust it on a class or global level. You can write your memory allocators and use them with the help of placement new.
What’s next?
As promised, I will write about the various flavors of memory management in C++ from top to bottom. I start in the next post with automatic memory management with smart pointers.
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, Matt Godbolt, and Honey Sukesan.
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)
Rainer Grimm
Yalovastraße 20
72108 Rottenburg
Mail: schulung@ModernesCpp.de
Mentoring: www.ModernesCpp.org
Modernes C++ Mentoring,
Leave a Reply
Want to join the discussion?Feel free to contribute!