Pointers/Memory Allocation   «Prev  Next»
Lesson 14 C++ deallocate() function
Objective How C++ deallocates memory

Purpose of C++ deallocate() Function in C++20

In C++20, there isn't a specific deallocate() function in the core language. There are concepts related to memory deallocation, particularly in the context of custom allocators or the std::allocator_traits which do indeed involve deallocation:
  1. std::allocator_traits::deallocate: This is part of the type traits for allocators. It's used to ensure that an allocator type Alloc has a deallocation method. Here's how it looks:
    • The std::allocator_traits<Alloc>::deallocate static member function is used to deallocate memory that was previously allocated. It calls the Alloc::deallocate function if it exists or falls back to default behavior if not explicitly provided by the allocator.

    Here's a basic example of how you might use it:
    #include <memory>
    #include <vector>
    
    int main() {
        std::allocator<int> alloc;
        int* p = alloc.allocate(1); // Allocate memory for one int
        alloc.deallocate(p, 1);     // Deallocate that memory
        return 0;
    }
    
    In this example:
    • alloc.allocate(1) allocates space for one integer.
    • alloc.deallocate(p, 1) deallocates that space, where p is the pointer to the memory and 1 indicates the number of elements that were initially allocated.
  2. Purpose:
    • Memory Management: The primary purpose of a deallocation function (like deallocate in std::allocator_traits) is to return memory back to the system or the memory pool when it's no longer needed, thus managing resources effectively.
    • Custom Allocators: For users implementing custom allocators, providing a deallocate method ensures that memory can be managed in a way that's consistent with the standard library containers which use allocators.
    • Polymorphic Memory Resources: With C++17's introduction of std::pmr::memory_resource, and its continued use in C++20, deallocate is crucial for managing memory resources in a more flexible, possibly runtime-polymorphic manner.
  3. C++20 Specifics: While C++20 doesn't introduce a new deallocate() function per se, it does enhance and extend the allocator model, particularly with concepts like std::polymorphic_allocator which can utilize these deallocation methods in more complex scenarios.

In summary, while there isn't a standalone deallocate() function added in C++20, the concept of deallocation is integral to memory management, especially in the context of allocators and container classes, ensuring proper resource management and preventing memory leaks.


The functionality to deallocate memory is closely related to memory management and there isn't one single C++ library that exclusively handles it.
Instead, it's spread across a few key areas:
  1. The <cstdlib> header: This header provides the C-style memory management functions:
    • malloc(): Allocates a block of memory.
    • free(): Deallocates memory previously allocated by malloc(), calloc(), or realloc().
    • calloc(): Allocates a block of memory and initializes it to zero.
    • realloc(): Resizes a previously allocated block of memory.
  2. The <memory> header: This header provides more modern C++ memory management facilities:
    • new and delete operators: These operators allocate and deallocate memory for objects, respectively.
    • std::allocator: A class template that provides a standard way to allocate and deallocate memory.
    • std::allocator_traits: Provides a consistent interface to allocator types, including the deallocate() member function you mentioned.
    • Smart pointers (std::unique_ptr, std::shared_ptr, std::weak_ptr): These automatically manage memory deallocation, preventing memory leaks.
  3. <new> header: This header defines components that control allocation and deallocation of memory, including how new and delete expressions behave.
In summary, deallocation is a core aspect of memory management in C++, and the specific functions and classes you use will depend on your needs and the style of memory management you're employing.


Examine the array deallocation function.

The deallocate() function in our dynamic, multidimensional array program deallocates the storage allocated by the operator new.
void deallocate(twod& m){
  for (int i = 0; i < m.column_size; ++i)
     delete [] m.base[i];
  delete [] m.base;
  m.row_size = 0;
  m.column_size = 0;
}

Deallocation works in reverse order to allocation. Each row is deallocated using delete []. It would be a mistake to deallocate m.base first, resulting in a system-dependent error. Only after each row of doubles is returned to free store can the column of pointers represented by m.base be safely deleted.
Next, we will look at the function that determines the maximum element of the array.

Why a destructor is needed

There are many reasons why a destructor may be needed. For example, an object may need to deallocate memory that it had previously allocated or it may need to close a file that it had opened. In C++, it is the destructor that handles deactivation events. The destructor has the same name as the constructor, but it is preceded by a ~. For example, here is the stack class and its constructor and destructor.
// This creates the class stack.
class stack {
int stck[SIZE];
int tos;
public:
stack(); // constructor
~stack(); // destructor
void push(int i);
int pop();
};
// stack's constructor
stack::stack()
{
tos = 0;
cout <<  "Stack Initialized\n";
}
// stack's destructor
stack::~stack()
{
cout <<  "Stack Destroyed\n";
}

Notice that, like constructors, destructors do not have return values.

SEMrush Software