Im having some problems to handle constructor exception in derived classes. When the derived class constructor throws an error, but the parent class has allocated some objects. Will the parent class destructor be called?
Example:
class A
{
A() { /* Allocate some stuff */ };
virtual ~A() { /* Deallocate stuff */ };
};
class B : public A
{
B()
{
/* Do some allocations */
...
/* Something bad happened here */
if (somethingBadHappened)
{
/* Deallocate B Stuff */
...
/* Throws the error */
throw Error; /* Will A destructor be called? I know B destructor won't */
};
};
~B() { /* Deallocate B Stuff */ };
}
And i was wondering if it is a good idea to do the following:
B()
{
/* Do some allocations */
...
/* Something bad happened here */
if (somethingBadHappened)
{
/* Deallocate B Stuff */
this->~B();
/* Throws the error */
throw Error; /* Will A destructor be called? I know B destructor won't */
};
};
If not, whats is a decent way to do such things?
An exception will cause the stack to unwind to a point where the exception is properly caught. This means that any objects created in the scope prior to where the exception is thrown will be destructed, including base class objects as in this example.
Try this:
#include <iostream>
class A
{
public:
A() { std::cout << "A::A()\n";}
~A() {std::cout << "A::~A()\n";}
};
class B : public A
{
public:
B()
{
std::cout << "B::B()\n";
throw 'c';
}
// note: a popular point of confusion --
// in this example, this object's destructor
// WILL NOT BE CALLED!
~B()
{
std::cout << "B::~B()\n";
}
};
int main()
{
try
{
B b;
}
catch(...)
{
std::cout << "Fin\n";
}
return 0;
}
Output should be: (note B::~B() is not called)
A::A()
B::B()
A::~A()
Fin
Calling the destructor manually as you've shown in your question will be safe as long as you don't try to free resources that you've not yet allocated. Better to wrap those resources in some type of RAII container (std::auto_ptr, boost::shared_ptr, etc.)to avoid the necessity of calling the destructor.
Mooing Duck has provided a very nice illustration of how the stack unwinding works when an exception is thrown in a constructor:
Your abortive attempt to write a clean constructor B::B() in the second part of the question highlights the awkwardness of a design that takes too much responsibility in one class. If you use only single-responsibility components, you can often get away with not writing any explicit error checks at all and let the exception handling mechanism do its work, recursively.
Consider this:
B::B()
{
try { this->p1 = get_dangerous_pointer(); }
catch(...) { throw; } // OK
try { this->p2 = suicidal_function(); }
catch(...) {
clean_up(p1);
throw;
}
try { this->p3 = get_monstrous_amounts_of_memory(); }
catch(...)
{
clean_up(p2);
clean_up(p1);
throw;
}
}
As you can see, writing a correct constructor for a class that has even just three different responsibilities is a maintenance nightmare.
The correct solution is to make each resource owned by a wrapper class whose only responsibility is to own that resource, and clean-up happens automagically even in the face of the most exceptional exception.
Also note that you have to be extremely careful when calling member functions from within any constructor. An object's lifetime doesn't begin until after a constructor has finished, so while you're in the constructor you're working with an "object under construction" - a bit like open-heart surgery... on yourself. In particular, you mustn't call the destructor, because you are only allowed to destroy complete objects.
The best idea is to catch exceptions within the construct and then put the object into a state where things will produce the errors (e.g. object to read file, opening file in constructor fails, then the read will not work).
Just keep the object consistent.
Haven't thought this all the way through but maybe consider creating the object in a try/catch block. If the constructor throws an exception, delete the object if it was created using new.
try
{
B* b = new B();
}
catch
{
delete b;
//log error
}
If you do not use new to allocate memory for b, you do not need to call delete in the catch block.
Make sure that your B destructor doesn't call delete on objects that were never created. I would recommend setting all members that are pointers to objects equal to 0 in your constructor before doing anything that could cause an exception. That way, if the destructor is called, deleteing them is safe.
Related
I just want to make sure that i understood the reference correctly.
I got a class A that contains that sets the unique pointer within it's constructor
class CDebug
{
//....
public:
~CDebug();
}
class A
{
public:
A()
{
pDebug = unique_ptr<CDebug>(new CDebug());
if(nullptr == pDebug)
{
CException ex("Nullpointer", __FILE__,__LINE__);
throw ex;
}
}
private:
unique_ptr<CDebug> pDebug;
}
Now when an instance of A leaves it scope:
Delete Operator is called automatically on the unique Pointer object
to free the heap
This forces the Destructor ~CDebug() to run
Now am I right or do i get any memory leaks here?
To answer your question: no, memory will not be leaked. Whenever object A goes out of scope, the destructor will be called, where destructor for CDebug will be called and memory freed.
But as I am very happy when people want to learn how to use unique_ptr, I wanted to point out two things with the code.
Firstly, the nullptr check in the constructor for A is redundant.
A()
{
pDebug = unique_ptr<CDebug>(new CDebug()); //throws at bad allocation
if(nullptr == pDebug) // will never be true
{
CException ex("Nullpointer", __FILE__,__LINE__);
throw ex;
}
}
, pDebug will never be nullptr. If allocation with new fails, std::bad_alloc will be thrown. Unless, of course, you are working with a compiler that does not support exception handling.
Secondly - assuming you have a C++14-compiler - avoid using new. Create a unique_ptr by calling std::make_unique(). Not only does it have the advantage that new/delete are removed from code, but it is also exception safe (see https://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/).
A()
{
pDebug = std::make_unique<CDebug>();
[...]
}
Also, if you do not absolutely have to throw a custom exception in the code, put the construction in the initializer list.
A() : pDebug(std::make_unique<CDebug>()) {}
In C++ if we define a class destructor as:
~Foo(){
return;
}
upon calling this destructor will the object of Foo be destroyed or does
explicitly returning from the destructor mean that we don't ever want to destroy it.
I want to make it so that a certain object is destroyed only through another objects destructor i.e. only when the other object is ready to be destroyed.
Example:
class Class1{
...
Class2* myClass2;
...
};
Class1::~Class1(){
myClass2->status = FINISHED;
delete myClass2;
}
Class2::~Class2(){
if (status != FINISHED) return;
}
I searched online and couldn't seem to find an answer to my question.
I've also tried figuring it out myself by going through some code step by step with a debugger but can't get a conclusive result.
No, you can't prevent the object from being destroyed by return statement, it just means the execution of the dtor's body will end at that point. After that it still will be destroyed (including its members and bases), and the memory still will be deallocated.
You migth throw exception.
Class2::~Class2() noexcept(false) {
if (status != FINISHED) throw some_exception();
}
Class1::~Class1() {
myClass2->status = FINISHED;
try {
delete myClass2;
} catch (some_exception& e) {
// what should we do now?
}
}
Note it's a terrible idea indeed. You'd better to reconsider the design, I'm sure there must be a better one. Throwing exception won't stop the destruction of its bases and members, just make it possible to get the process result of Class2's dtor. And what could be done with it is still not clear.
~Foo(){
return;
}
means exactly the same as:
~Foo() {}
It is similar to a void function; reaching the end without a return; statement is the same as having return; at the end.
The destructor contains actions that are performed when the process of destroying a Foo has already begun. It's not possible to abort a destruction process without aborting the entire program.
[D]oes explicitly returning from the destructor mean that we don't ever want to destroy it?
No. An early return (via return; or throw ...) only means the rest of the body of the destructor is not executed. The base and members are still destroyed and their destructors still run, see [except.ctor]/3.
For an object of class type of any storage duration whose initialization or destruction is terminated by an exception, the destructor is invoked for each of the object's fully constructed subobjects...
See below for code samples of this behaviour.
I want to make it so that a certain object is destroyed only through another objects destructor i.e. only when the other object is ready to be destroyed.
It sounds like the question is rooted in the issue of ownership. Deleting the "owned" object only once the parent is destroyed in a very common idiom and achieved with one of (but not limited to);
Composition, it is an automatic member variable (i.e. "stack based")
A std::unique_ptr<> to express exclusive ownership of the dynamic object
A std::shared_ptr<> to express shared ownership of a dynamic object
Given the code example in the OP, the std::unique_ptr<> may be a suitable alternative;
class Class1 {
// ...
std::unique_ptr<Class2> myClass2;
// ...
};
Class1::~Class1() {
myClass2->status = FINISHED;
// do not delete, the deleter will run automatically
// delete myClass2;
}
Class2::~Class2() {
//if (status != FINISHED)
// return;
// We are finished, we are being deleted.
}
I note the if condition check in the example code. It hints at the state being tied to the ownership and lifetime. They are not all the same thing; sure, you can tie the object reaching a certain state to it's "logical" lifetime (i.e. run some cleanup code), but I would avoid the direct link to the ownership of the object. It may be a better idea to reconsider some of the semantics involved here, or allow the "natural" construction and destruction to dictate the object begin and end states.
Side note; if you have to check for some state in the destructor (or assert some end condition), one alternative to the throw is to call std::terminate (with some logging) if that condition is not met. This approach is similar to the standard behavior and result when an exception is thrown when unwinding the stack as a result of an already thrown exception. This is also the standard behavior when a std::thread exits with an unhandled exception.
[D]oes explicitly returning from the destructor mean that we don't ever want to destroy it?
No (see above). The following code demonstrates this behaviour; linked here and a dynamic version. The noexcept(false) is needed to avoid std::terminate() being called.
#include <iostream>
using namespace std;
struct NoisyBase {
NoisyBase() { cout << __func__ << endl; }
~NoisyBase() { cout << __func__ << endl; }
NoisyBase(NoisyBase const&) { cout << __func__ << endl; }
NoisyBase& operator=(NoisyBase const&) { cout << __func__ << endl; return *this; }
};
struct NoisyMember {
NoisyMember() { cout << __func__ << endl; }
~NoisyMember() { cout << __func__ << endl; }
NoisyMember(NoisyMember const&) { cout << __func__ << endl; }
NoisyMember& operator=(NoisyMember const&) { cout << __func__ << endl; return *this; }
};
struct Thrower : NoisyBase {
Thrower() { cout << __func__ << std::endl; }
~Thrower () noexcept(false) {
cout << "before throw" << endl;
throw 42;
cout << "after throw" << endl;
}
NoisyMember m_;
};
struct Returner : NoisyBase {
Returner() { cout << __func__ << std::endl; }
~Returner () noexcept(false) {
cout << "before return" << endl;
return;
cout << "after return" << endl;
}
NoisyMember m_;
};
int main()
{
try {
Thrower t;
}
catch (int& e) {
cout << "catch... " << e << endl;
}
{
Returner r;
}
}
Has the following output;
NoisyBase
NoisyMember
Thrower
before throw
~NoisyMember
~NoisyBase
catch... 42
NoisyBase
NoisyMember
Returner
before return
~NoisyMember
~NoisyBase
According to the C++ Standard (12.4 Destructors)
8 After executing the body of the destructor and destroying any
automatic objects allocated within the body, a destructor for class X
calls the destructors for X’s direct non-variant non-static data
members, the destructors for X’s direct base classes and, if X is the
type of the most derived class (12.6.2), its destructor calls the
destructors for X’s virtual base classes. All destructors are called
as if they were referenced with a qualified name, that is, ignoring
any possible virtual overriding destructors in more derived classes.
Bases and members are destroyed in the reverse order of the completion
of their constructor (see 12.6.2). A return statement (6.6.3) in a
destructor might not directly return to the caller; before
transferring control to the caller, the destructors for the members
and bases are called. Destructors for elements of an array are called
in reverse order of their construction (see 12.6).
So a returning statement does not prevent the object for which the destructor is called to be destroyed.
does explicitly returning from the destructor mean that we don't ever want to destroy it.
No.
The destructor is a function so you can use the return keyword inside of it but that won't prevent the destruction of the object, once you are inside the destructor you are already destroying your object so any logic that wants to prevent that will have to occur before.
For some reason i intuitively think your design problem can be solved with a shared_ptr and maybe a custom deleter, but that would require more info on the said problem.
All stack-based objects inside will get destructed, no matter how soon you return from the destructor. If you miss to delete dynamically allocated objects, then there would be intentional memory leak.
This is the whole idea how move-constructors would work. The move CTOR would simply take original object's memory. The destructor of original object simply wont/cant call delete.
No. return just means exit the method, it doesn't stop the destruction of the object.
Also, why would you want to? If the object is allocated on the stack and you somehow managed to stop destruction then the object would live on a reclaimed part of the stack that will probably be overwritten by the next function call, which may write all over your objects memory and create undefined behavior.
Likewise, if the object is allocated on the heap and you managed to prevent destruction you'd have a memory leak as the code calling delete would assume that it didn't need to hold on to a pointer to the object whilst it's actually still there and taking up memory that nobody is referencing.
Of course not. Explicit call of 'return' ist 100% equivalent to implicit returning after execution of the destructor.
You can make a new method to make the object "commit suicide" and keep the destructor empty, so something like this will do the job you would like to do:
Class1::~Class1()
{
myClass2->status = FINISHED;
myClass2->DeleteMe();
}
void Class2::DeleteMe()
{
if (status == FINISHED)
{
delete this;
}
}
Class2::~Class2()
{
}
So, as all the others pointed out, return is not a solution.
The first thing I would add is that you shouldn't usually worry about this. Unless your professor explicitly asked.
It would be very odd if you could't trust the external class to only delete your class at the right time, and I figure no one else is seeing it.
If the pointer is passed around, the pointer would very probably be shared_ptr/weak_ptr, and let it destroy your class at the right moment.
But, hey, it's good to wonder how we would solve an odd problem if it ever arose, if we learn something (and don't waste time while on a deadline!)
So what for a solution? If you can at least trust the destructor of Class1 not to destroy your object too early, then you can just declare the destructor of Class2 as private, and then declare the destructor of Class1 as friend of Class2, like this:
class Class2;
class Class1 {
Class2* myClass2;
public:
~Class1();
};
class Class2 {
private:
~Class2();
friend Class1::~Class1();
};
Class1::~Class1() {
delete myClass2;
}
Class2::~Class2() {
}
As a bonus, you don't need the 'status' flag; which is good -if someone wanted this bad to screw with you, why wouldn't set the status flag to FINISHED anywhere else, and then call delete?
This way, you have actual guarantee that the object can be destroyed nowhere else than in the destructor of Class1.
Of course, the destructor of Class1 gets access to all private members of Class2. It might not matter -after all, Class2 is about to be destroyed anyway! But if it does, we can conjure even more convoluted ways to work around it; why not. For instance:
class Class2;
class Class1 {
private:
int status;
Class2* myClass2;
public:
~Class1();
};
class Class2Hidden {
private:
//Class2 private members
protected:
~Class2Hidden();
public:
//Class2 public members
};
class Class2 : public Class2Hidden {
protected:
~Class2();
friend Class1::~Class1();
};
Class1::~Class1() {
delete myClass2;
}
Class2Hidden::~Class2Hidden() {
}
Class2::~Class2() {
}
This way the public members will still be available in the derived class, but the private members will actually be private. ~Class1 will only get access to the private and protected members of Class2, and the protected members of Class2Hidden; which in this case is only the destructors.
If you need to keep a protected member of Class2 protected from the destructor of Class1... there are ways, but it really depends on what you are doing.
Good luck!
For this case you could use a class-specific overload of the delete operator.
So for you Class2 you could something like this
class Class2
{
static void operator delete(void* ptr, std::size_t sz)
{
std::cout << "custom delete for size " << sz << '\n';
if(finished)
::operator delete(ptr);
}
bool Finished;
}
Then if you set the finished to true before the delete, the actual deletion will be called.
Note that i haven't tested it, i just modified the code that i've found here
http://en.cppreference.com/w/cpp/memory/new/operator_delete
Class1::~Class1()
{
class2->Finished = true;
delete class2;
}
I was going over this article
and it states
Note: if a constructor finishes by throwing an exception, the memory
associated with the object itself is cleaned up — there is no memory
leak. For example:
void f()
{
X x; // If X::X() throws, the memory for x itself will not leak
Y* p = new Y(); // If Y::Y() throws, the memory for *p itself will not leak
}
I am having difficulty understanding this and would appreciate it if someone could clarify this. I tried the following example which shows that incase of an exception inside a constructor the destructor would not be called.
struct someObject
{
someObject()
{
f = new foo();
throw 12;
}
~someObject()
{
std::cout << "Destructor of someobject called";
}
foo* f;
};
class foo
{
public:
foo()
{
g = new glue();
someObject a;
}
~foo()
{
std::cout << "Destructor of foo";
}
private:
glue* g;
};
int main()
{
try
{
foo a;
}
catch(int a)
{
//Exception caught. foo destructor not called and someobject destrucotr not called.
//Memory leak of glue and foo objects
}
}
How would I fix this issue ?
Sorry for the inconvenience the update might have caused.
"... the destructor would not be called."
Since the object isn't considered as constructed yet, after the constructor failed with an exception, the destructor won't be called.
Object allocation, and construction (merely destruction) are different things.
Any objects allocated using new() before the exception is thrown will leak.
You shouldn't manage these resources yourself, unless you're really, really, really need it, and are about 100% sure about what you're doing.
Rather use suitable smart pointers for class members from the standard dynamic memory management library.
When the constructor throws, no destructor will be called. When an
exception is thrown inside a constructor there are several things that
you should take note of in terms of properly handling resource
allocations that may have occured in the aborted construction of the
object:
the destructor for the object being constructed will not be called.
destructors for member objects contained in that object's class will be called
the memory for the object that was being constructed will be freed.
Thanks for all the response.
I reformatted my question to understand the state of the member pointer after the containg class constructor throws an exception
Again my example class :)
class Foo
{
public:
Foo()
{
int error = 0;
p = new Fred;
throw error; // Force throw , trying to understand what will happen to p
}
~Foo()
{
if (p)
{
delete p;
p = 0;
}
}
private:
Fred* p;
};
int main()
{
try
{
Foo* lptr = new Foo;
}
catch (...)
{}
}
The consturctor for class foo would throw an exception for some random reason. I understand that the desturctor of foo will never be called but in this case will the destructor for p get called?
what difference it makes to have p as a boost smart pointer than a raw pointer to fred.
Thanks.
There is a similar question here that covers what your asking.
In this case, if the call to new fails, then the memory for the pointer is guaranteed to be freed. If the call succeeds, and the constructor throws after that, you will have a memory leak.
The destructor of the class will not be called, because the object was never fully constructed. There are two ways to fix this.
1)
Have exceptions fully managed in the constructor:
class Foo
{
public:
Foo()
try
{
p = new p;
throw /* something */;
}
catch (...)
{
delete p;
throw; //rethrow. no memory leak
}
private:
int *p;
};
2)
Or use a smart pointer. When a constructor is entered, all of its members have been constructed. And because when a constructor throws, and objects members have been constructed, they must be destructed. And a smart pointer fixes that:
class Foo
{
public:
Foo() :
p(new int)
{
throw /* something */;
}
private:
std::auto_ptr<int> p;
};
Not if it was never allocated.
But instead of NULL being returned by bad allocations via new, you will get an exception std::bad_alloc.
NULL gets returned by C malloc if an allocation cannot be made.
You are also correct that if an object is not fully constructed, it will not be destructed. So if you have a successful allocation on the heap in a constructor, and then an exception is thrown, that will lead to a memory leak.
You could also consider having a zombie state instead of throwing an exception. Some of the standard C++ library does this. In which case the object is not in a valid state and can be checked if it is in a valid state via another method.
Generally throwing exceptions in constructors is best though.
See my answer here for an extended discussion.
The destructor for p will not be called, if the memory allocation for p fails.
The question really doesn't make any sense. new Fred(); will never return NULL. It will only ever either successfully create a Fred object, or throw an exception. If it threw an exception, the Fred object would never have existed, so it's destructor would not be called.
class someclass {};
class base
{
int a;
int *pint;
someclass objsomeclass;
someclass* psomeclass;
public:
base()
{
objsomeclass = someclass();
psomeclass = new someclass();
pint = new int();
throw "constructor failed";
a = 43;
}
}
int main()
{
base temp();
}
In the above code, the constructor throws. Which objects will be leaked, and how can the memory leaks be avoided?
int main()
{
base *temp = new base();
}
How about in the above code? How can the memory leaks be avoided after the constructor throws?
Yes it will leak memory. When the constructor throws, no destructor will be called (in this case you don't show a destructor that frees the dynamically allocated objects, but lets assume you had one).
This is a major reason to use smart pointers - since the smart poitners are full fledged objects, they will get destructors called during the exception's stack unwind and have the opportunity to free the memory.
If you use something like Boost's scoped_ptr<> template, your class could look more like:
class base{
int a;
scoped_ptr<int> pint;
someclass objsomeclass;
scoped_ptr<someclass> psomeclass;
base() :
pint( new int),
objsomeclass( someclass()),
psomeclass( new someclass())
{
throw "constructor failed";
a = 43;
}
}
And you would have no memory leaks (and the default dtor would also clean up the dynamic memory allocations).
To sum up (and hopefully this also answers the question about the
base* temp = new base();
statement):
When an exception is thrown inside a constructor there are several things that you should take note of in terms of properly handling resource allocations that may have occured in the aborted construction of the object:
the destructor for the object being constructed will not be called.
destructors for member objects contained in that object's class will be called
the memory for the object that was being constructed will be freed.
This means that if your object owns resources, you have 2 methods available to clean up those resources that might have already been acquired when the constructor throws:
catch the exception, release the resources, then rethrow. This can be difficult to get correct and can become a maintenance problem.
use objects to manage the resource lifetimes (RAII) and use those objects as the members. When the constructor for your object throws an exception, the member objects will have desctructors called and will have an opportunity to free the resource whose lifetimes they are responsible for.
Both new's will be leaked.
Assign the address of the heap created objects to named smart pointers so that it will be deleted inside the smart pointers destructor that get call when the exception is thrown - (RAII).
class base {
int a;
boost::shared_ptr<int> pint;
someclass objsomeclass;
boost::shared_ptr<someclass> psomeclass;
base() :
objsomeclass( someclass() ),
boost::shared_ptr<someclass> psomeclass( new someclass() ),
boost::shared_ptr<int> pint( new int() )
{
throw "constructor failed";
a = 43;
}
};
Now psomeclass & pint destructors will be called when the stack unwind when the exception is thrown in the constructor, and those destructors will deallocate the allocated memory.
int main(){
base *temp = new base();
}
For ordinary memory allocation using (non-plcaement) new, memory allocated by the operator new is freed automatically if the constructor throws an exception. In terms of why bother freeing individual members (in response to comments to Mike B's answer), the automatic freeing only applies when an exception is thrown in a constructor of an object being new'ly allocated, not in other cases. Also, the memory that is freed is those allocated for the object members, not any memory you might have allocated say inside the constructor. i.e. It would free the memory for the member variables a, pint, objsomeclass, and psomeclass, but not the memory allocated from new someclass() and new int().
I believe that the top answer is wrong and would still leak memory.
The destructor for the class members will not be called if the constructor throws an exception (because it never completed its initialization, and perhaps some members have never reached their constructor calls).
Their destructors are only called during the class's destructor call. That only makes sense.
This simple program demonstrates it.
#include <stdio.h>
class A
{
int x;
public:
A(int x) : x(x) { printf("A constructor [%d]\n", x); }
~A() { printf("A destructor [%d]\n", x); }
};
class B
{
A a1;
A a2;
public:
B()
: a1(3),
a2(5)
{
printf("B constructor\n");
throw "failed";
}
~B() { printf("B destructor\n"); }
};
int main()
{
B b;
return 0;
}
With the following output (using g++ 4.5.2):
A constructor [3]
A constructor [5]
B constructor
terminate called after throwing an instance of 'char const*'
Aborted
If your constructor fails partway then it is your responsibility to deal with it. Worse, the exception may be thrown from your base class' constructor!
The way to deal with these cases is by employing a "function try block" (but even then you must carefully code the destruction of your partially initialized object).
The correct approach to your problem would then be something like this:
#include <stdio.h>
class A
{
int x;
public:
A(int x) : x(x) { printf("A constructor [%d]\n", x); }
~A() { printf("A destructor [%d]\n", x); }
};
class B
{
A * a1;
A * a2;
public:
B()
try // <--- Notice this change
: a1(NULL),
a2(NULL)
{
printf("B constructor\n");
a1 = new A(3);
throw "fail";
a2 = new A(5);
}
catch ( ... ) { // <--- Notice this change
printf("B Cleanup\n");
delete a2; // It's ok if it's NULL.
delete a1; // It's ok if it's NULL.
}
~B() { printf("B destructor\n"); }
};
int main()
{
B b;
return 0;
}
If you run it you will get the expected output where only the allocated objects are destroyed and freed.
B constructor
A constructor [3]
B Cleanup
A destructor [3]
terminate called after throwing an instance of 'char const*'
Aborted
You can still work it out with smart shared pointers if you want to, with additional copying. Writing a constructor similar to this:
class C
{
std::shared_ptr<someclass> a1;
std::shared_ptr<someclass> a2;
public:
C()
{
std::shared_ptr<someclass> new_a1(new someclass());
std::shared_ptr<someclass> new_a2(new someclass());
// You will reach here only if both allocations succeeded. Exception will free them both since they were allocated as automatic variables on the stack.
a1 = new_a1;
a2 = new_a2;
}
}
Good luck,
Tzvi.
If you throw in a constructor, you should clean up everything that came before the call to throw. If you are using inheritance or throwing in a destructor, you really shouldn't be. The behaviour is odd (don't have my standard handy, but it might be undefined?).
Yes, that code will leak memory. Blocks of memory allocated using "new" are not freed when an exception is raised. This is part of the motivation behind RAII.
To avoid the memory leak, try something like this:
psomeclass = NULL;
pint = NULL;
/* So on for any pointers you allocate */
try {
objsomeclass = someclass();
psomeclass = new someclass();
pint = new int();
throw "constructor failed";
a = 43;
}
catch (...)
{
delete psomeclass;
delete pint;
throw;
}
Everything you "new" needs to be deleted, or you'll cause a memory leak. So these two lines:
psomeclass = new someclass();
pint = new int();
Will cause memory leaks, because you need to do:
delete pint;
delete psomeclass;
In a finally block to avoid them being leaked.
Also, this line:
base temp = base();
Is unnecessary. You just need to do:
base temp;
Adding the "= base()" is unnecessary.
you need to delete psomeclass... Its not necessary to clean up the integer...
RWendi