new and throw in c'tor

C

Chameleon

--------------------------------
class A {
int data[1000];
public:
A() { throw; }
};

int main(int, char**) {
try {
A *a = new A;
} catch(...) {}
}
--------------------------------

In code above we have a class which throws in c'tor. Object *a never
created, so d'tor of A never runs.

sizeof(A) is 1000 * sizeof(int), so with new, a block of (not always)
4000 bytes allocated in memory but pointer to that block, never stored
in 'a'. So 'delete a;' is not working.

The question is:
We have a memory leak here?
If yes, how we can fix it?

Thanks
 
M

mlimber

Chameleon said:
--------------------------------
class A {
int data[1000];
public:
A() { throw; }
};

int main(int, char**) {
try {
A *a = new A;
} catch(...) {}
}
--------------------------------

In code above we have a class which throws in c'tor. Object *a never
created, so d'tor of A never runs.

sizeof(A) is 1000 * sizeof(int), so with new, a block of (not always)
4000 bytes allocated in memory but pointer to that block, never stored
in 'a'. So 'delete a;' is not working.

The question is:
We have a memory leak here?
If yes, how we can fix it?

Thanks

There's no leak. See this FAQ for what happens behind the scenes when
you use the new operator (search for "functionally"):

http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14

Cheers! --M
 
R

Ron Natalie

Chameleon said:
--------------------------------
class A {
int data[1000];
public:
A() { throw; }
};

int main(int, char**) {
try {
A *a = new A;
} catch(...) {}
}

In the code above you end up in terminate because you are doing a
rethrow outside of the context of a handled exception. You want to
throw an object:
throw 0;
sizeof(A) is 1000 * sizeof(int), so with new, a block of (not always)
4000 bytes allocated in memory but pointer to that block, never stored
in 'a'. So 'delete a;' is not working.

The question is:
We have a memory leak here?
If yes, how we can fix it?
No you don't have a memory leak here (provided you fix the screwup
above). If an exception occurs during new, the memory is returned
via the deallocation function. The only thing you must be careful
of is that the constructor must clean up after itself:

class A {
int* foo;
public:
A() {
foo = new int[1000];
throw 0;
}
};

Here it the allocation stored in foo is leaked .
 
P

Peter

Chameleon said:
--------------------------------
class A {
int data[1000];
public:
A() { throw; }
};

int main(int, char**) {
try {
A *a = new A;
} catch(...) {}
}
--------------------------------

In code above we have a class which throws in c'tor. Object *a never
created, so d'tor of A never runs.

sizeof(A) is 1000 * sizeof(int), so with new, a block of (not always)
4000 bytes allocated in memory but pointer to that block, never stored
in 'a'. So 'delete a;' is not working.

The question is:
We have a memory leak here?
If yes, how we can fix it?


Welcome to the world of C++-Exception-Handling.

I'm curious that this question does not come up more often.
I guess most programmers ignore C++ Exception handling.
It is the most underused feature of C++.
But you gain incredible code savings if you do not have to check for
success anymore.
Also it is the only way to abort the construction of an object.
This way you can do your fallible allocation where it belongs -- inside
the constructor.
Also it enables very rich error reporting.
Consider catching and rethrowing an new exception object containing a
copy of the caught exception object. This way you can easily create
code, which gives useful rich error messages, like:

Cannot compile file, because of
Cannot preprocess file, because of
Cannot create temporary file, because of
Disk Full!
 

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

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top