How is memory deallocated after an exception in a constructor?

F

Fred Zwarts

Hello,

I am trying to debug some complex debug code.
In order to track the use of dynamically allocated memory,
I replaced the standard global new and delete operators.
(Not for changing the memory allocation algorithm, but
for gathering some statistics and to find memory leaks.)
This seems to work.

However, I noticed that my replacing delete operator is not called
in the case that an attempt is made to create an object of a class
using the new operator and an exception is thrown in the constructor.

My question is how the memory which was allocated for this object is
deallocated. Apparently the global delete operator is not used.

Cheers,
F.Z.
 
P

peter.koch.larsen

Fred Zwarts skrev:
Hello,

I am trying to debug some complex debug code.
In order to track the use of dynamically allocated memory,
I replaced the standard global new and delete operators.
(Not for changing the memory allocation algorithm, but
for gathering some statistics and to find memory leaks.)
This seems to work.

However, I noticed that my replacing delete operator is not called
in the case that an attempt is made to create an object of a class
using the new operator and an exception is thrown in the constructor.
It should be.
My question is how the memory which was allocated for this object is
deallocated. Apparently the global delete operator is not used.
Try it again. If you have:

class C {...};

C* c = newC();

and C's constructor throws, then the memory will be freed via delete.

Please notice that:
class B;
class C
{
C() { D* pd = new D; throw 0; }
};

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

Here memory for D will be leaked.

/Peter
 
A

Andre Kostur

Hello,

I am trying to debug some complex debug code.
In order to track the use of dynamically allocated memory,
I replaced the standard global new and delete operators.
(Not for changing the memory allocation algorithm, but
for gathering some statistics and to find memory leaks.)
This seems to work.

However, I noticed that my replacing delete operator is not called
in the case that an attempt is made to create an object of a class
using the new operator and an exception is thrown in the constructor.

My question is how the memory which was allocated for this object is
deallocated. Apparently the global delete operator is not used.

<sarcasm>As I gaze into my crystal ball, I can obviously see that your
problem is that your computer isn't facing at exactly 43 degrees.</sarcasm>

Show us the code. We can't help you if we can't see what you're doing.
Remember to reduce the problem to the minimum amount of compilable code
that exhibits the problem.
 
F

Fred Zwarts

Fred Zwarts skrev:

It should be.

Try it again. If you have:

class C {...};

C* c = newC();

and C's constructor throws, then the memory will be freed via delete.

Thanks for answering my question. It has set me on the right track,
I believe and I am closer to a solution. May I ask a few related questions
to check that I understand it correctly.

*) Consider now the following:

C* c = new C[3];

After allocating memory for the whole array, the constructor for each
array element is called. Suppose, however, that the constructor for the
second array element throws an exception. Is it true that the constructor
for the third element is not called, the destructor for the first element is
called and then the operator delete[] is called?

*) Suppose the class C overloads the global new and delete operators,
(defining these operators with the same parameter list). Then this class-specific
new operator will be used to allocate memory. If then the constructor
throws an exception, the class specific delete operator will be used to
deallocate memory. Is this true?

*) Suppose someone wants to implement another memory allocation
method and needs another operator new with an extra parameter
(the type of this parameter is not relevant).
Then he uses

C * c = new (X) C();

Now no operator delete is called if the constructor throws an exception.
Is it possible to deallocate the memory allocated by this modified new operator?
The pointer c has not yet received the result of the new operator,
so it cannot be use in a catch construction.

Thanks for your help in understanding these issues.

F.Z.
 
F

Fred Zwarts

Andre Kostur said:
<sarcasm>As I gaze into my crystal ball, I can obviously see that your
problem is that your computer isn't facing at exactly 43 degrees.</sarcasm>

Show us the code. We can't help you if we can't see what you're doing.
Remember to reduce the problem to the minimum amount of compilable code
that exhibits the problem.

May be you should by yourself a flat screen to replace your crystal ball.
It would make it much easier to read text.

If you don't understand plain English, please, ignore it. Apparently
other people were able to understand the question and reply with
useful answers.
 
P

peter.koch.larsen

Fred said:
Fred Zwarts skrev:

It should be.

Try it again. If you have:

class C {...};

C* c = newC();

and C's constructor throws, then the memory will be freed via delete.

Thanks for answering my question. It has set me on the right track,
I believe and I am closer to a solution. May I ask a few related questions
to check that I understand it correctly.

*) Consider now the following:

C* c = new C[3];

After allocating memory for the whole array, the constructor for each
array element is called. Suppose, however, that the constructor for the
second array element throws an exception. Is it true that the constructor
for the third element is not called, the destructor for the first element is
called and then the operator delete[] is called?
Yes.


*) Suppose the class C overloads the global new and delete operators,
(defining these operators with the same parameter list). Then this class-specific
new operator will be used to allocate memory. If then the constructor
throws an exception, the class specific delete operator will be used to
deallocate memory. Is this true?
Yes.


*) Suppose someone wants to implement another memory allocation
method and needs another operator new with an extra parameter
(the type of this parameter is not relevant).
Then he uses

C * c = new (X) C();

Now no operator delete is called if the constructor throws an exception.
Is it possible to deallocate the memory allocated by this modified new operator?

Yes. Just write the corresponding operator delete.
The pointer c has not yet received the result of the new operator,
so it cannot be use in a catch construction.

Nothing prevents c to "receive" the value of the call to the new
operator. c contains garbage, but the compiler writer might know
better.
 
F

Fred Zwarts

Thanks for answering these questions. I think I start to understand how this all works.
However, your answer to my last question was not completely clear to me:
Yes. Just write the corresponding operator delete.

But the compiler does not know which delete operator corresponds to this modified
new operator. So, the compiler will not automatically create a call to the
corresponding operator delete.
Am I still right?
Nothing prevents c to "receive" the value of the call to the new
operator. c contains garbage, but the compiler writer might know
better.

This is no clear to me. What has the compiler writer to do with it?
Do you want to say that the return value of the operator new (X)
is first assigned to c and that the call to the constructor is a next step?
Is this the order in which these steps must take place?

Maybe my question is not clear. I understand that in cases where the
operator new has more parameters, the programmer is responsible
for calling the corresponding delete (if needed).
My understanding is that in such a case the compiler
will not automatically create a call to some delete operator
when the constructor throws an exception. The exception cannot be
handled in the new operator, because the constructor is called after
the return of the operator new.
So one could use a try and catch block to handle this situation:

C * c;
try {
c = new (X) C();
} catch (int i) {
???
}

Suppose the constructor of C throws an int.
What can be put in place of the question marks? Is c defined at this point?
A delete operator cannot be used, because the object has not been created,
so the destructor should not be called. (But another memory deallocation
function could be called, instead.) But is the pointer c valid at this point?
How would a programmer prevent a memory leak in this case?

Thanks for your attention.
F.Z.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top