7
votes

In C++, for every time new [] is used or delete [] is used, how many times does each one allocate or deallocate memory? My question is more specific to using them on classes with their respective constructors and destructor.

Such as, take the following class:

#include <iostream>

class Cell
{
public:
    Cell() : _value(2)
    {
        std::cout << "Cell being made!\n";
    }
    ~Cell()
    {
        std::cout << "Cell being freed!\n";
    }

    const int& getVal() const
    {
        return _value;
    }
private:
    int _value;
};

Now, say an array of that class type is needed, and new[] is used, as below

Cell* cells = new Cell[5];

When this is run in an executable or program, I also see the following printed to stdout:

Cell being made!
Cell being made!
Cell being made!
Cell being made!
Cell being made!

And subsequently when delete[] is called on the cells pointer, I see:

Cell being freed!
Cell being freed!
Cell being freed!
Cell being freed!
Cell being freed!

My question is, in every constructor call, is the size of memory equal to one class instance being allocated? Such as does new Cell[5] allocate memory 5 times? Or does it allocate once and then make 5 calls to the constructor as just a function call? Same with delete[], does it deallocate at every destructor call?

3
Note that there are typically two levels of allocation, from new and from the OS. It's common for new to be implemented as a sub-allocator; it only asks the OS for big memory blocks and sub-divides it when the program needs smaller blocks.MSalters

3 Answers

17
votes

You are mixing two different concepts:

  1. Memory allocation/deallocation
  2. Object construction/destruction

new and delete do both for us.

new Cell[5];

Total memory needed for all 5 objects are allocated in a single memory allocation operation. It can't be 5 allocations as 5 different allocations can't guarantee consecutive spaces.

After allocating memory for 5 objects, new must initialize 5 objects by calling default constructor. Here we have 5 separate constructor calls.

Similar things happen during delete [] cells. It have to destroy 5 objects by calling destructor of 5 different objects. Then all allocated memory is freed in one single deallocation operation.

0
votes

If a (keyword as opposed to operator) new [] succeeds it allocate a single block large enough to hold all the objects, at which point the objects are then constructed into that block. Likewise, a (keyword) delete [] will invoke the destructor for each object in the array then deallocate the entire block.

The new and delete (and new [] and delete[]) operators perform the actual allocation/deallocation and will be invoked one time for any given use of the new/new[] and delete/delete[] keywords.

0
votes

The instruction Cell* cells = new Cell[5]; means you create 5 Cell objects lying consecutive on Heap area( of main memory). While cells is a pointer lying on Stack area( of main memory) that points to the objects( cells will just store address of the first object). After that, each object will call default constructor to initiate its value so you will see 5 lines Cell being made!.

When you do not want to use the objects and want to free it from Heap memory you must use delete [] cells instruction. Then, 5 object that cells points to will call 5 destructors to do something before the objects are removed from memory,but cells is still exists on Stack memory and it can be used to point to another Cell object( cells will be removed from area only when cells out of its scope, now just 5 objects on heap memory are removed). So you can see 5 lines Cell being freed!