iBacchus
iBacchus

Reputation: 175

Why is new[] allocating extra memory?

I'm reading "Thinking in C++" and I'm confused by the new operator. Here is the code from the book:

//: C13:ArrayOperatorNew.cpp
// Operator new for arrays

#include <new> // Size_t definition
#include <fstream>

using namespace std;

ofstream trace("ArrayOperatorNew.out");

class Widget 
{
    enum { sz = 10 };
    int i[sz];

  public:

    Widget() { trace << "*"; }
    ~Widget() { trace << "~"; }

    void* operator new(size_t sz) 
    {
        trace << "Widget::new: "
              << sz << " bytes" << endl;
        return ::new char[sz];
    }

    void operator delete(void* p) 
    {
        trace << "Widget::delete" << endl;
        ::delete []p;
    }

    void* operator new[](size_t sz) 
    {
        trace << "Widget::new[]: "
              << sz << " bytes" << endl;
        return ::new char[sz];
    }

    void operator delete[](void* p) 
    {
        trace << "Widget::delete[]" << endl;
        ::delete []p;
    }
};

int main() 
{
    trace << "new Widget" << endl;
    Widget* w = new Widget;
    trace << "\ndelete Widget" << endl;
    delete w;
    trace << "\nnew Widget[25]" << endl;
    Widget* wa = new Widget[25];
    trace << "\ndelete []Widget" << endl;
    delete []wa;
} ///:~

and here is the content of the trace in "ArrayOperatorNew.out"

new Widget
Widget::new: 40 bytes
*
delete Widget
~Widget::delete
new Widget[25]
Widget::new[]: 1004 bytes
*************************
delete []Widget
~~~~~~~~~~~~~~~~~~~~~~~~~
Widget::delete[]

I'm confused about the number 1004. Why it's not 1000? The book says:

This extra four bytes is where the system keeps information about the array, in particular, the number of objects in the array.

But what's the system? How is this accomplished? Compiler helps here?

Upvotes: 3

Views: 285

Answers (5)

Idan K
Idan K

Reputation: 20881

When using new[] the runtime needs some way to remember the size of the array allocated, so it knows how much to deallocate when using delete[]. In your particular implementation it's way of remembering is allocating the extra four bytes which hold the size (it doesn't have to work this way).

You can read more about this in the C++ FAQ.

Upvotes: 5

Tobias Langner
Tobias Langner

Reputation: 10828

The memory management has to keep some information about the size of the memory block. Without that information, delete / delete[] can not work correctly (in case of delete, this information may not be necessary sinc the compiler knows the size of object being deleted).

How the information is kept and where is an implementation detail of new/delete. It may change depending on the compiler or the memory management library you use (e.g. SmartHeap).

Sometimes additional memory is allocated to detect programming errors (like writing over the boundary of allocated memory).

Upvotes: 0

Alon
Alon

Reputation: 4952

When allocating an array with new then, an additional word is used in the beginning of the allocated block to keep the number of allocated bytes.
As the C++ array do not keep information about their size, the memory manager must keep tabs over the size of allocated memory, when delete[] is used the number of allocated byes is read and then the memory manager fees that amount of memory. that is the reason why calling delete[] for a single variable can be disastrous and calling delete for an array causes a memory leak.

Upvotes: 0

sharptooth
sharptooth

Reputation: 170509

That's a compiler-dependent detail.

When delete[] is invoked it is passed only one parameter - the pointer to the array. In order to run correctly it has to know the number of elements to execute the destructors on exactly the right number of objects. So it has to get that information somewhere.

The typical approach is that new[] prepends the array payload with an extra size_t that stores the number of elements. Thus the amount of space allocated will be

sizeof( size_t ) + numberOfElements * sizeof ( ObjectType )

Upvotes: 1

Related Questions