I have been thinking for some time now about this question, but I have not found an answer online satisfactory enough, yet. So here I am.
Assumptions
For the sake of clarity let us restrict ourselves to C++11 and a custom object. By custom object, I mean a user-defined class that the developer has full control of. All the code snippets below are not meant to be compilable or even syntactically correct. They just illustrate a concept.
Boundary conditions
Our object has a nontrivial constructor that can throw exceptions if an error is encountered. When constructing this object I would like to catch and deal with the exceptions as close as possible to the object creation point, to make the code more readable and catching only the constructor exceptions and nothing else.
Example 1
This example is not ideal because this is exactly what I am trying to avoid: dealing with constructor exceptions far away from the constructor.
class MyClass {
public:
MyClass() {
throw 1;
}
}
int main() {
try {
MyClass my_obj;
try {
// Do something with my_obj that may throw
} catch (...) {
// deal with exceptions
}
} catch(...) {
// deal with constructor exceptions
}
}
Example 2
Here I use a std::unique_ptr to separate the object declaration and initialization. The downside is that I now create the object on the heap instead of the stack even if I have no strong reason to do that.
class MyClass {
public:
MyClass() {
throw 1;
}
}
int main() {
std::unique_ptr<MyClass> my_obj_ptr;
try {
my_obj_ptr = boost::make_unique<MyClass>();
} catch (...) {
// deal with constructor exceptions
}
// continue to use my_obj
}
Example 3
Modify the object internal state and check that.
class MyClass {
private:
good_internal_state;
public:
MyClass() : good_internal_state(true) {
try {
throw 1;
} catch(...) {
good_internal_state = false;
}
}
bool IsInternalStateGood() {
return good_internal_state;
}
}
int main() {
MyClass my_obj;
if (!my_obj.IsInternalStateGood()) {
// Do something
}
// continue to use my_obj
}
Right now I am leaning towards the Example 2 case but I would like to know what is the most syntactically correct way to accomplish what I want.
I wouldn't say any of those versions is more or less correct (except for some typos). Example 2 looked like the one I would use. Here scoping seems to be the largest problem. The variable needs to declared outside of the try but must be initialized inside. If you don't like to use the heap std::optional could be usefull:
int main() {
std::optional<MyClass> maybeMyClass;
try {
maybeMyClass.emplace(/*constructor parameters*/);
} catch (...) {
// deal with constructor exceptions
}
// continue to use my_obj
maybeMyClass->foo();
}
Allthough the syntax could imply otherwise, the value managed by std::optional is allocated as the footprint of this std::optional (on the stack in this case).
You could also use a factory function createMyClass that would return a std::optional, this would require MyClass to have a move constructor, which shouldn't be to expensive.
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.
To allocate dynamic memory, I have been using vectors all this time in C++.
But recently, while reading some source code, I found the use of "new int[size]" and on some research, found that it too allocates dynamic memory.
Can anyone give me advice as to which is better? I am looking from an algorithmic and ICPC point of view?
Always prefer the standard containers. They have well-defined copying semantics, are exception safe, and release properly.
When you allocate manually, you must guarantee that the release code is executed, and as members, you must write correct copy assignment and copy constructor which does the right thing without leaking in case of exception.
Manual:
int *i = 0, *y = 0;
try {
i = new int [64];
y = new int [64];
} catch (...) {
delete [] y;
delete [] i;
}
If we want our variables to have only the scope they really need, it gets smelly:
int *i = 0, *y = 0;
try {
i = new int [64];
y = new int [64];
// code that uses i and y
int *p;
try {
p = new int [64];
// code that uses p, i, y
} catch(...) {}
delete [] p;
} catch (...) {}
delete [] y;
delete [] i;
Or just:
std::vector<int> i(64), y(64);
{
std::vector<int> p(64);
}
It is a horror to implement that for a class that has copy semantics. Copying may throw, allocation may throw, and we want transaction semantics, ideally. An example would burst this answer tho.
Ok here.
Copyable class - Manual resource management vs containers
We have this innocent looking class. As it turns out, it is pretty evil. I feel reminded of American McGee's Alice:
class Foo {
public:
Foo() : b_(new Bar[64]), f_(new Frob[64]) {}
private:
Bar *b_;
Frob *f_;
};
Leaks. Most beginner C++ programmers recognize that there's missing deletes. Add them:
class Foo {
public:
Foo() : b_(new Bar[64]), f_(new Frob[64]) {}
~Foo() { delete f_; delete b_; }
private:
Bar *b_;
Frob *f_;
};
Undefined behavior. Intermediate C++ programmers recognize that the wrong delete-operator is used. Fix this:
class Foo {
public:
Foo() : b_(new Bar[64]), f_(new Frob[64]) {}
~Foo() { delete [] f_; delete [] b_; }
private:
Bar *b_;
Frob *f_;
};
Bad design, leaks and double deletes lurk there if the class is copied. The copying itself is fine, the compiler cleanly copies the pointers for us. But the compiler won't emit code to create copies of the arrays.
Slightly more experienced C++ programmers recognize that the Rule of Three was not respected, which says that if you have explicitly written any of destructor, copy assignment or copy constructor, you probably also need to write out the others, or make them private without implementation:
class Foo {
public:
Foo() : b_(new Bar[64]), f_(new Frob[64]) {}
~Foo() { delete [] f_; delete [] b_; }
Foo (Foo const &f) : b_(new Bar[64]), f_(new Frob[64])
{
*this = f;
}
Foo& operator= (Foo const& rhs) {
std::copy (rhs.b_, rhs.b_+64, b_);
std::copy (rhs.f_, rhs.f_+64, f_);
return *this;
}
private:
Bar *b_;
Frob *f_;
};
Correct. ... Provided you can guarantee to never run out of memory and that neither Bar, nor Frob can fail on copying. Fun starts in next section.
The wonderland of writing exception safe code.
Construction
Foo() : b_(new Bar[64]), f_(new Frob[64]) {}
Q: What happens if the initialization of f_ fails?
A: All Frobs that have been constructed are destroyed. Imagine 20 Frob were constructed, the 21st will fail. Than, in LIFO order, the first 20 Frob will be correctly destroyed.
That's it. Means: You have 64 zombie Bars now. The Foos object itself never comes to life, its destructor will therefore not be called.
How to make this exception safe?
A constructor should always succeed completely or fail completely. It shouldn't be half-live or half-dead. Solution:
Foo() : b_(0), f_(0)
{
try {
b_ = new Bar[64];
f_ = new Frob[64];
} catch (std::exception &e) {
delete [] f_; // Note: it is safe to delete null-pointers -> nothing happens
delete [] b_;
throw; // don't forget to abort this object, do not let it come to life
}
}
Copying
Remember our definitions for copying:
Foo (Foo const &f) : b_(new Bar[64]), f_(new Frob[64]) {
*this = f;
}
Foo& operator= (Foo const& rhs) {
std::copy (rhs.b_, rhs.b_+64, b_);
std::copy (rhs.f_, rhs.f_+64, f_);
return *this;
}
Q: What happens if any copy fails? Maybe Bar will have to copy heavy resources under the hood. It can fail, it will.
A: At the time-point of exception, all objects copied so far will remain like that.
This means that our Foo is now in inconsistent and unpredictable state. To give it transaction semantics, we need to build up the new state fully or not at all, and then use operations that cannot throw to implant the new state in our Foo. Finally, we need to clean up the interim state.
The solution is to use the copy and swap idiom (http://gotw.ca/gotw/059.htm).
First, we refine our copy constructor:
Foo (Foo const &f) : f_(0), b_(0) {
try {
b_ = new Bar[64];
f_ = new Frob[64];
std::copy (rhs.b_, rhs.b_+64, b_); // if this throws, all commited copies will be thrown away
std::copy (rhs.f_, rhs.f_+64, f_);
} catch (std::exception &e) {
delete [] f_; // Note: it is safe to delete null-pointers -> nothing happens
delete [] b_;
throw; // don't forget to abort this object, do not let it come to life
}
}
Then, we define a non-throwing swap function
class Foo {
public:
friend void swap (Foo &, Foo &);
};
void swap (Foo &lhs, Foo &rhs) {
std::swap (lhs.f_, rhs.f_);
std::swap (lhs.b_, rhs.b_);
}
Now we can use our new exception safe copy-constructor and exception-safe swap-function to write an exception-safe copy-assignment-operator:
Foo& operator= (Foo const &rhs) {
Foo tmp (rhs); // if this throws, everything is released and exception is propagated
swap (tmp, *this); // cannot throw
return *this; // cannot throw
} // Foo::~Foo() is executed
What happened? At first, we build up new storage and copy rhs' into it. This may throw, but if it does, our state is not altered and the object remains valid.
Then, we exchange our guts with the temporary's guts. The temporary gets what is not needed anymore, and releases that stuff at the end of scope. We effectively used tmp as a garbage can, and properly choose RAII as the garbage collection service.
You may want to look at http://gotw.ca/gotw/059.htm or read Exceptional C++ for more details on this technique and on writing exception safe code.
Putting it together
Summary of what can't throw or is not allowed to throw:
copying primitive types never throws
destructors are not allowed to throw (because otherwise, exception safe code would not be possible at all)
swap functions shall not throw** (and C++ programmers as well as the whole standard library expect it to not throw)
And here is finally our carefully crafted, exception safe, corrected version of Foo:
class Foo {
public:
Foo() : b_(0), f_(0)
{
try {
b_ = new Bar[64];
f_ = new Frob[64];
} catch (std::exception &e) {
delete [] f_; // Note: it is safe to delete null-pointers -> nothing happens
delete [] b_;
throw; // don't forget to abort this object, do not let it come to life
}
}
Foo (Foo const &f) : f_(0), b_(0)
{
try {
b_ = new Bar[64];
f_ = new Frob[64];
std::copy (rhs.b_, rhs.b_+64, b_);
std::copy (rhs.f_, rhs.f_+64, f_);
} catch (std::exception &e) {
delete [] f_;
delete [] b_;
throw;
}
}
~Foo()
{
delete [] f_;
delete [] b_;
}
Foo& operator= (Foo const &rhs)
{
Foo tmp (rhs); // if this throws, everything is released and exception is propagated
swap (tmp, *this); // cannot throw
return *this; // cannot throw
} // Foo::~Foo() is executed
friend void swap (Foo &, Foo &);
private:
Bar *b_;
Frob *f_;
};
void swap (Foo &lhs, Foo &rhs) {
std::swap (lhs.f_, rhs.f_);
std::swap (lhs.b_, rhs.b_);
}
Compare that to our initial, innocent looking code that is evil to the bones:
class Foo {
public:
Foo() : b_(new Bar[64]), f_(new Frob[64]) {}
private:
Bar *b_;
Frob *f_;
};
You better don't add more variables to it. Sooner or later, you will forget to add proper code at some place, and your whole class becomes ill.
Or make it non-copyable.
class Foo {
public:
Foo() : b_(new Bar[64]), f_(new Frob[64]) {}
Foo (Foo const &) = delete;
Foo& operator= (Foo const &) = delete;
private:
Bar *b_;
Frob *f_;
};
For some classes this makes sense (streams, for an instance; to share streams, be explicit with std::shared_ptr), but for many, it does not.
The real solution.
class Foo {
public:
Foo() : b_(64), f_(64) {}
private:
std::vector<Bar> b_;
std::vector<Frob> f_;
};
This class has clean copying semantics, is exception safe (remember: being exception safe does not mean to not throw, but rather to not leak and possibly have transaction semantics), and does not leak.
In just about any situation, std::vector is preferable. It has a destructor to free the memory, whereas manually managed memory must be explicitly deleted once you've finished with it. It is very easy to introduce memory leaks, for example if something throws an exception before it is deleted. For example:
void leaky() {
int * stuff = new int[10000000];
do_something_with(stuff);
delete [] stuff; // ONLY happens if the function returns
}
void noleak() {
std::vector<int> stuff(10000000);
do_something_with(stuff);
} // Destructor called whether the function returns or throws
It is also more convenient if you need to resize or copy the array.
The only reason to prefer a raw array is if you have extreme performance or memory limitations. vector is a larger object than a pointer (containing size and capacity information); and it will sometimes value-initialise its objects, while a raw array will default-initialise them (which, for trivial types, means they are left uninitialised).
In the rare cases when these issues might be important, you should consider std::unique_ptr<int[]>; it has a destructor which will prevent memory leaks, and has no run-time overhead when compared to a raw array.
I don't think that there's ever a case where new int[size] is preferable. You'll sometimes see it in pre-standard code, but even then, I don't think it was ever a good solution; in pre-standard days, if you didn't have an equivalent to std::vector in your tool kit, you wrote one. The only reasons you might want to use a new int[size] is in the implementation of a pre-standard vector class. (My own separated allocation and initialization, like the containers in the standard library, but this might be overkill for a very simple vector class.)
Even though both methods allocates dynamic memory, one is an object made for handling data of arbitrary length (std::vector<T>), while the other is just a pointer to a sequential line of memory slots of size N (ints in this case).
Among other differences
A std::vector<T> will automatically resize the allocated memory for your data if you try to append a new value and it runs out of space. A int * will not.
A std::vector<T> will free the allocated memory when the vector goes out of scope, a int * will not.
A int * will have little to no overhead (compared to the vector), though std::vector<T> isn't exactly a new thing and is normally very optimized. Your bottle neck will probably be elsewhere.
But a std::vector<int> will always consume more memory than a int *, and some operations will always take a little more time.
So if there are memory/CPU limitations and you want to shave off every single cycle that you possible can.. use an int *.
There are situations where one is definitely preferable over the other!
When you need "raw"/"real" memory and full control over it, operator new is your best bet.
For example when you are using placement new.
by raw/real memory I mean something that is not managed through a wrapper-container, such as std::vector<T>.
When you are looking for a container to handle arbitrary and don't want to reinvent the wheel regarding memory management; std::vector<T> (or any other appropriate STL container)
Can anyone give me advice as to which is better?
Vector is better when
You haven't learned to do manual memory management.
You have learned of it, but aren't confident yet.
You think you know how to do it, but are unwittingly overconfident.
You really know what you're doing, but might make a mistake.
You are a guru and none of the above applies, but your code might be later maintained by a colleague, for whom any of the above does apply.
...
Pretty much always.
Manual memory management can easily and often does lead to memory leaks, and worse yet, undefined behaviour.
Internally the vector do exactly the same also it will make care about the memory release. So there is no any reason to use the new operator. std::vector is a part of c++, it is standard, it is tested and it is safe, don't use the raw pointer when you have some standard way to do your work.
If you need a dynamically sized sequence of objects, use a vector. If you need to allocate raw memory and manage that memory yourself, allocate memory. You will find that sometimes vectors are more useful, and at other times a flat memory buffer is better.
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.
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.