does "new" initialize memory? call default constructor?

Started by
8 comments, last by JohnBolton 19 years, 4 months ago
on page 129 of the c++ programming language (special edition) book, it says "The standard implementations of operator new() and operator new[]() do not initialize the memory returned." but on page 246, it says "An object created on the free store has its constructor invoked by the new operator..." what's the relationship between these two statements?
Advertisement
If you have a class C and you call

C* c = new C(...parameters...);

then the compiler will do these things:

C* c = (C*)new(sizeof(C));
c->C(...parameters...);

You see that new only allocates the memory (maybe using malloc) of some size, and returns a void* to that memory. The compiler then generates a cast to store the void* as C* and calls the constructor on that object.

Since you can overload operator new like this:

void* operator new(size_t size) { ... }

you see that new is not responsible for calling the constructor, it is the compiler that generates the call.
"initialize the memory returned" refers to filling the memory with a default value. In debug mode, compilers often initialise memory with things like 0xCD so that you can catch errors to do with accidentally trying to use memory you haven't set with something valid. However in release mode, you should assume the memory is filled with random values.
In addition to what nmi said, PODs don't have a constructor so
int * p = new int[1000];

will allocate enough memory for at least 1000 ints but the values of p[0..999] are not guaranteed to be known (e.g. undefined).

[edit]
Too slow[smile]
[/edit]
new doesn't actually call the constructor inside the body of new and delete doesn't actually call the destructor inside the body of delete. The construction happens directly after a call to new and directly before a call to delete, both automatically behind the scenes. The seemingly subtle difference between new actually internally calling the constructor and having the constructor called automatically after new is finished is important, as it makes it so that if you overload new or delete, all that your function should do is allocate memory. This is because there is no way to call the constructor of an object on raw memory you allocate*, so it would be impossible to have new internally call the constructor (*without, of course, calling another form of new or placement new to construct the object inside of your new, which would in turn lead to an infinitely recursive definition of new, aka kaboom).

As well, remember that when new is called, it won't necessarily have type data. The non-placement overloaded new works without type data and the same new is called for all types, therefore it would be impossible to call the constructor inside of new even if there where a non-new command to do so in C++, since the type is unknown when inside of new (it could be any number of types). new would have to be changed to be a template, or require different definitions for every type, etc.
It's because operator new and the new operator are two different things. Operator new just allocates memory, while new operator initializes it.
Quote:Original post by fallenang3l
It's because operator new and the new operator are two different things. Operator new just allocates memory, while new operator initializes it.

Huh?
Quote:Original post by Anonymous Poster
Quote:Original post by fallenang3l
It's because operator new and the new operator are two different things. Operator new just allocates memory, while new operator initializes it.

Huh?


Didn't you get the memo? j/k
Example:
foo* f = new foo;
new is a language keyword (duh) that's an operator. It's precise name is new operator. It cannot be overridden. However, it calls a function called operator new (words swapped) that you can override to allocate memory however you want, but that it's. Operator new allocates, new operator calls the constructor and therefore it initializes.
And people say C++ is complicated :)
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Quote:Original post by Anonymous Poster
Quote:Original post by fallenang3l
It's because operator new and the new operator are two different things. Operator new just allocates memory, while new operator initializes it.

Huh?


Actually it is very straightforward. Compare these:
plus operator:   "+"minus operator:  "-"times operator:  "*"divide operator: "/"new operator:    "new"delete operator: "delete" 
to these:
    ... operator +(...) {...}    ... operator -(...) {...}    ... operator *(...) {...}    ... operator /(...) {...}    ... operator new(...) {...}    ... operator delete(...) {...} 
The operators in the first group cause the compiler to generate calls to the functions in the second group (in addition to other things).
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!

This topic is closed to new replies.

Advertisement