tags:

views:

98

answers:

6

Hi, I am trying to get better at c++. I have a Test class and below code in main().

Test *pObj = new Test();

If we debug by steping one by one instruction, First it goes to new function to allocate memory, then it calls constructor. Then it comes back to main() function. As we all know, constructor does not return anything. In that case, how come pObj will have the pointer which is allocated by new ? Any idea how it is implemented by compiler ?

A: 

The return value you should care about is the one 'returned' by new, in that case the address of the newly allocated object.

new can be implemented by a call to malloc for example, which truly return the address (edit: see comments bellow).

Cedric H.
What exactly do you mean by your last sentence? A `new` expression most certainly can't be replaced by a call to `malloc` as a constructor wouldn't be called.
Charles Bailey
I meant that the compiler can implement `new` as a call to malloc followed by a call to the constructor. Isn't it ?
Cedric H.
OK, but that's more explicit than what you wrote. The compiler can only do this if `malloc` returns memory as if it were returned by the standard `operator new`.
Charles Bailey
@Cedric: A `new T` expression will make a call to `operator new`, then use placement new to construct the object in that memory, then return that result of the placement new (ignoring exceptions). It cannot use `malloc` to get the memory, but not because it needs to have a constructor called (operator new wouldn't either); because the standard says so.
GMan
OK for `operator new` but what do you mean with "then use placement new to construct the object in that memory" ? At some point a call to `malloc` would be possible ?
Cedric H.
@Charles: Ok thx.
Cedric H.
Not only is it possible, in many cases a call to malloc is what actually happens inside of new, depending on the compiler and runtime libraries used.
Gerald
@Cedric: `operator new` is like `malloc`, except it's what `new` expressions use and it can be *replaced*. An implementation is free to implement `operator new` in terms of `malloc` if it wants, but it doesn't have to. Placement new is this syntax: `new (x) T()`, where a `T()` is constructed in the memory location `x`. It is the only way to explicitly invoke a constructor on some memory location. So `new T()` becomes something like: `void* __mem = operator new(sizeof(T)); T* result = new (__mem) T(); /* result */`, ignoring exceptions.
GMan
@GMan: OK I understand, i had 10% of the idea :p Thanks for the explanation !
Cedric H.
@Cedric: No problem.
GMan
A: 

I think, i got the answer. new operator allocates memory and makes a call to constructor. It will be passed this pointer as the same pointer that new allocated. Once constructor returns, control comes back to new operator implementation of compiler.(Not the main() function). Then, once new returns, as it gives the allocated pointer, pObj will have that pointer.

bjskishore123
+4  A: 

Yes.. The constructor didn't return anything.. But the new operator constructs and returns the allocated memory address of the instance of Test class which is being pointed by pObj..

liaK
+4  A: 

When you use a new expression the compiler generates code to allocate memory and then call the constructor on the allocated memory to create a new object. If successful, it returns a pointer to the new object.

Constructors have no return values, the compiler just adds a call to the constructor on a piece of memory where it needs the new object to be constructed. It's not necessary for the constructor to return the location of the object, the code already knews where the object must be; it (effectively) passed it to the constructor.

Charles Bailey
A: 

new and delete are operators. By default the new operator allocates the memory for the object, and returns the pointer to that memory. A constructor is then called if one exists for the object being created, based on the syntax of what comes after the new operator. The object is already allocated before the constructor is called, so the constructor doesn't need to return anything. It is essentially a void method that is called after allocation.

The global new operator is often implemented as a function, such as void* new(size_t s), where s is the size of the object to be allocated. The compiler figures the size of the object to be created under the hood and passes it to new, returns the pointer to the allocated memory, and then calls the constructor.

You can override the new operator either globally or an a per-class basis to add your own behavior.

Gerald
A: 

$5.3.4/1 - "If the entity is a non-array object, the new-expression returns a pointer to the object created. If it is an array, the new-expression returns a pointer to the initial element of the array."

Note the new expression and operator new are not one and same thing.

$5.3.4/8- "If the allocated type is a non-array type, the allocation function’s name is operator new and the deallocation function’s name is operator delete. If the allocated type is an array type, the allocation function’s name is operator new[] and the deallocation function’s name is operator delete[]."

Chubsdad