Effective C++ Third Edition 55 Specific Ways to Improve Your Programs and Designs
In these days of computing environments boasting built-in support for garbage collection (e.g., Java and .NET), the manual C++ approach to memory management can look rather old-fashioned. Yet many developers working on demanding systems applications choose C++ because it lets them manage memory manually. Such developers study the memory usage characteristics of their software, and they tailor their allocation and deallocation routines to offer the best possible performance (in both time and space) for the systems they build. Doing that requires an understanding of how C++'s memory management routines behave, and that's the focus of this chapter. The two primary players in the game are the allocation and deallocation routines (operator new and operator delete), with a supporting role played by the new-handler the function called when operator new can't satisfy a request for memory. Memory management in a multithreaded environment poses challenges not present in a single-threaded system, because the heap is a modifiable global resource, thus rife with opportunities for the race conditions that bedevil access to all such resources in threaded systems. Many Items in this chapter mention the use of modifiable static data, always something to put thread-aware programmers on high alert. Without proper synchronization, the use of lock-free algorithms, or careful design to prevent concurrent access, calls to memory routines can easily lead to corrupted heap management data structures. Rather than repeatedly remind you of this danger, I'll mention it here and assume that you keep it in mind for the rest of the chapter. Something else to keep in mind is that operator new and operator delete apply only to allocations for single objects. Memory for arrays is allocated by operator new[] and deallocated by operator delete[]. (In both cases, note the "[]" part of the function names.) Unless indicated otherwise, everything I write about operator new and operator delete also applies to operator new[] and operator delete[]. Finally, note that heap memory for STL containers is managed by the containers' allocator objects, not by new and delete directly. That being the case, this chapter has nothing to say about STL allocators. |