Deallocating objects vs. deallocating storage
I recently wrote a couple of articles on the distinction between allocating objects and allocating raw storage.1, 2 In essence, when a program allocates an object, it not only allocates storage for the object but also initializes that storage with a value appropriate for the type of object that will occupy that storage. When a program just allocates storage, it leaves that storage uninitialized. Calling storage "raw" is a common way to emphasize that it's not initialized.
The distinction between storage and objects is readily apparent in the behavioral difference between the Standard C malloc function and a C++ new-expression. Specifically, a C (or C++) expression such as:
pw = (widget *)malloc(sizeof(widget));
allocates raw storage. Indeed, the malloc call allocates storage that's big enough and suitably aligned to hold an object of type widget, but it leaves that storage uninitialized. In contrast, a C++ new-expression as in:
pw = new widget ();
creates a widget object with a coherent initial value.
The distinction between storage and objects carries over when allocating array objects. A call to malloc as in:
pw = (widget *)malloc(10 * sizeof(widget));
allocates raw storage for an array of 10 widgets. By contrast, the C++ array new-expression in:
pw = new widget ;
allocates an array of 10 properly initialized widgets.
Each new-expression is conceptually, if not actually, a two-step process: (1) allocate storage for an object, and (2) initialize it. For objects of class types, initializing an object usually involves calling a constructor. An array new-expression is also a two-step process, but the second step is a loop that initializes every array element.
It should come as no surprise that the distinction between objects and raw storage also comes into play when you deallocate them. Just as allocating an object in C++ may involve calling a constructor, deallocating an object may involve calling a destructor.
This month I'll explain how delete-expressions interact with destructors and deallocation functions in C++. I'll also explain how C programmers can employ a style of memory deallocation that mimics the behavior of C++ delete-expressions.