Containers crash inside structs? - c++

I can't seem to write to std containers vector, map and multimap (only ones I've tried) when accessing them in structs. Here's an example of what I'm trying to do:
struct B
{
void* pp;
};
struct A
{
std::vector< B* > veEvents;
};
in a class function somewhere
A* d = new A;
B* f = new B;
d->veEvnts.push_back( f ); //<< this line crashes
Trying to access a container in this fashion crashes STD. It crashes in the STD code on lines refencing this pointers. I've tried several workarounds including typedef'ing the vector statement but that didn't work. The one that seems to have promise as a workaround was putting a function inside a struct and calling the function...
struct B
{
void* pp;
};
struct A
{
void K( B* f )
{
static std::vector< B* > veEvents;
veEvnts.push_back( f ); //<< this line crashes
}
};
in some class function
A* a = new A;
B* b = new B;
a->K(b); //This seems to work.
Is there any way around the initial problem where accessing the container declared inside a struct causes an access problem?

All right! Got to the bottom of it. Ivaylo was right about there being stack corruption. The pointer in question pointed to a vector on a class's member variable area. The vector was originally created there, copied to another struct of the same struct type on the heap but the vector still pointed to the class stack. I tried writing a deep copy but from a different class. That didn't work. So I created a struct on the heap from the start and used that to save variables on the first pass. Later, in a different class, with the struct on the heap, access to the vector works. The original struct should have been created that way in the first place. Thanks again guys. I appreciate all your help.

Is that the complete code for class 'B' ? If yes, then there is no obvious problem in code pasted. If no, then one of the possible scenarios leading to crash could be:
Class B allocates memory to *pp while creating new object but doesn't do the same while copying (i.e. shallow copy in copy constructor).
When you insert an object in vector, it calls copy constructor to copy your object into vector memory space. Due to shallow copy, both the object inserted and its counterpart inside vector share the same pointer pointed by pp.
Now the object goes out of scope and destructor deletes memory pointed by pp. Vector counterpart of this object still points to this memory and trying to access that somewhere.
When you try to do the same thing through static reference, no deletion happens (static object won't be deleted once out of scope). Both your object and corresponding object inside vector keep pointing to valid memory and no crash happens.

Related

In Which Situations To Delete A Pointer

My following question is on memory management. I have for example an int variable not allocated dynamically in a class, let's say invar1. And I'm passing the memory address of this int to another classes constructor. That class does this:
class ex1{
ex1(int* p_intvar1)
{
ptoint = p_intvar1;
}
int* ptoint;
};
Should I delete ptoint? Because it has the address of an undynamically allocated int, I thought I don't need to delete it.
And again I declare an object to a class with new operator:
objtoclass = new ex1();
And I pass this to another class:
class ex2{
ex2(ex1* p_obj)
{
obj = p_obj;
}
ex1* obj;
};
Should I delete obj when I'm already deleting objtoclass?
Thanks!
Because it has the address of an undynamically allocated int I thought I don't need to delete it.
Correct.
Should I delete obj when I'm already deleting objtoclass?
No.
Recall that you're not actually deleting pointers; you're using pointers to delete the thing they point to. As such, if you wrote both delete obj and delete objtoclass, because both pointers point to the same object, you'd be deleting that object twice.
I would caution you that this is a very easy mistake to make with your ex2 class, in which the ownership semantics of that pointed-to object are not entirely clear. You might consider using a smart pointer implementation to remove risk.
just an appendix to the other answers
You can get rid of raw pointers and forget about memory management with the help of smart pointers (shared_ptr, unique_ptr).
The smart pointer is responsible for releasing the memory when it goes out of scope.
Here is an example:
#include <iostream>
#include <memory>
class ex1{
public:
ex1(std::shared_ptr<int> p_intvar1)
{
ptoint = p_intvar1;
std::cout << __func__ << std::endl;
}
~ex1()
{
std::cout << __func__ << std::endl;
}
private:
std::shared_ptr<int> ptoint;
};
int main()
{
std::shared_ptr<int> pi(new int(42));
std::shared_ptr<ex1> objtoclass(new ex1(pi));
/*
* when the main function returns, these smart pointers will go
* go out of scope and delete the dynamically allocated memory
*/
return 0;
}
Output:
ex1
~ex1
Should I delete obj when I'm already deleting objtoclass?
Well you could but mind that deleting the same object twice is undefined behaviour and should be avoided. This can happen for example if you have two pointers for example pointing at same object, and you delete the original object using one pointer - then you should not delete that memory using another pointer also. In your situation you might as well end up with two pointers pointing to the same object.
In general, to build a class which manages memory internally (like you do seemingly), isn't trivial and you have to account for things like rule of three, etc.
Regarding that one should delete dynamically allocated memory you are right. You should not delete memory if it was not allocated dynamically.
PS. In order to avoid complications like above you can use smart pointers.
You don't currently delete this int, or show where it's allocated. If neither object is supposed to own its parameter, I'd write
struct ex1 {
ex1(int &i_) : i(i_) {}
int &i; // reference implies no ownership
};
struct ex2 {
ex2(ex1 &e_) : e(e_) {}
ex1 &e; // reference implies no ownership
};
int i = 42;
ex1 a(i);
ex2 b(a);
If either argument is supposed to be owned by the new object, pass it as a unique_ptr. If either argument is supposed to be shared, use shared_ptr. I'd generally prefer any of these (reference or smart pointer) to raw pointers, because they give more information about your intentions.
In general, to make these decisions,
Should I delete ptoint?
is the wrong question. First consider things at a slightly higher level:
what does this int represent in your program?
who, if anyone, owns it?
how long is it supposed to live, compared to these classes that use it?
and then see how the answer falls out naturally for these examples:
this int is an I/O mapped control register.
In this case it wasn't created with new (it exists outside your whole program), and therefore you certainly shouldn't delete it. It should probably also be marked volatile, but that doesn't affect lifetime.
Maybe something outside your class mapped the address and should also unmap it, which is loosely analogous to (de)allocating it, or maybe it's simply a well-known address.
this int is a global logging level.
In this case it presumably has either static lifetime, in which case no-one owns it, it was not explicitly allocated and therefore should not be explicitly de-allocated
or, it's owned by a logger object/singleton/mock/whatever, and that object is responsible for deallocating it if necessary
this int is being explicitly given to your object to own
In this case, it's good practice to make that obvious, eg.
ex1::ex1(std::unique_ptr<int> &&p) : m_p(std::move(p)) {}
Note that making your local data member a unique_ptr or similar, also takes care of the lifetime automatically with no effort on your part.
this int is being given to your object to use, but other objects may also be using it, and it isn't obvious which order they will finish in.
Use a shared_ptr<int> instead of unique_ptr to describe this relationship. Again, the smart pointer will manage the lifetime for you.
In general, if you can encode the ownership and lifetime information in the type, you don't need to remember where to manually allocate and deallocate things. This is much clearer and safer.
If you can't encode that information in the type, you can at least be clear about your intentions: the fact that you ask about deallocation without mentioning lifetime or ownership, suggests you're working at the wrong level of abstraction.
Because it has the address of an undynamically allocated int, I
thought I don't need to delete it.
That is correct. Simply do not delete it.
The second part of your question was about dynamically allocated memory. Here you have to think a little more and make some decisions.
Lets say that your class called ex1 receives a raw pointer in its constructor for a memory that was dynamically allocated outside the class.
You, as the designer of the class, have to decide if this constructor "takes the ownership" of this pointer or not. If it does, then ex1 is responsible for deleting its memory and you should do it probably on the class destructor:
class ex1 {
public:
/**
* Warning: This constructor takes the ownership of p_intvar1,
* which means you must not delete it somewhere else.
*/
ex1(int* p_intvar1)
{
ptoint = p_intvar1;
}
~ex1()
{
delete ptoint;
}
int* ptoint;
};
However, this is generally a bad design decision. You have to root for the user of this class read the commentary on the constructor and remember to not delete the memory allocated somewhere outside class ex1.
A method (or a constructor) that receives a pointer and takes its ownership is called "sink".
Someone would use this class like:
int* myInteger = new int(1);
ex1 obj(myInteger); // sink: obj takes the ownership of myInteger
// never delete myInteger outside ex1
Another approach is to say your class ex1 does not take the ownership, and whoever allocates memory for that pointer is the responsible for deleting it. Class ex1 must not delete anything on its destructor, and it should be used like this:
int* myInteger = new int(1);
ex1 obj(myInteger);
// use obj here
delete myInteger; // remeber to delete myInteger
Again, the user of your class must read some documentation in order to know that he is the responsible for deleting the stuff.
You have to choose between these two design decisions if you do not use modern C++.
In modern C++ (C++ 11 and 14) you can make things explicit in the code (i.e., do not have to rely only on code documentation).
First, in modern C++ you avoid using raw pointers. You have to choose between two kinds of "smart pointers": unique_ptr or shared_ptr. The difference between them is about ownership.
As their names say, an unique pointer is owned by only one guy, while a shared pointer can be owned by one or more (the ownership is shared).
An unique pointer (std::unique_ptr) cannot be copied, only "moved" from one place to another. If a class has an unique pointer as attribute, it is explicit that this class has the ownership of that pointer. If a method receives an unique pointer as copy, it is explicit that it is a "sink" method (takes the ownership of the pointer).
Your class ex1 could be written like this:
class ex1 {
public:
ex1(std::unique_ptr<int> p_intvar1)
{
ptoint = std::move(p_intvar1);
}
std::unique_ptr<int> ptoint;
};
The user of this class should use it like:
auto myInteger = std::make_unique<int>(1);
ex1 obj(std::move(myInteger)); // sink
// here, myInteger is nullptr (it was moved to ex1 constructor)
If you forget to do "std::move" in the code above, the compiler will generate an error telling you that unique_ptr is not copyable.
Also note that you never have to delete memory explicitly. Smart pointers handle that for you.

Do I need to delete a vector?

I am defining a vector as a private variable of a class Grid. Class Points has only two instance vars that are all ints but the number of points will only be known when I read this in from the file, so I guess I have to make Points dynamically with new which means I have to destroy them later. Did I initialize constructor correctly and When writing a destructor for Grid do I need to write a destructor for vector like this: ~vecotr() or with delete or using iterator?
class Grid{
public:
// initialize vector with 3 points with val 0.
Grid(vector<Points> v) : vector<Points>(3, 0) {}; // is this right
// first option
~Grid() {
~vector<Points>(); // not sure how to destroy vector<Points>;
}
// second option
~Grid() {
delete v_points;
}
// third option
~Grid() {
for (vector<Points>::iterator it = v_points.begin(),
vector<Points>::iterator it_end = v_points.end(); it != it_end; it++)
}
private:
vector<Points> v_points;
};
Which option should I use and did I initialize constructor correctly?
If object is not allocate with new, you do not need to explicitly destroy it.
The member objects will be automatically destroyed in the reverse order of their declaration. In your case there is no need to even create a destructor as the automatic one will suffice.
If for some reason you do have member objects allocated with new, you also have to create custom copy construct and assignment operator otherwise you run into troubles of sharing the same member object across multiple instances.
I will reply because predecessors answered only to the question from topic while you are asking more questions and I will also give some advice. In the remainder of this post we will assume that if Points do allocate any dynamic memory, the memory is returned properly when Points are deleted.
Class Points has only two instance vars that are all ints but the
number of points will only be known when I read this in from the file,
so I guess I have to make Points dynamically with new which means I
have to destroy them later.
This comes with contradiction to what you actually do here
class Grid{
public:
// initialize vector with 3 points with val 0.
Grid(vector<Points> v) : vector<Points>(3, 0) {}; // is this right
private:
vector<Points> v_points;
};
because you create vector without new. However this might be OK if we assume that you first get number of Points and then you are about to create a Grid. std::vector is not C array and might be easily resized, assigned and gives much more flexibility. You do not have to create it on heap because you are afraid about size: vector elements are always created on heap, it is just a vector itself that is (if it is) on stack. And this is often exactly what we want (see i.e. RAII). The proper way to initialize a vector would be then
class Grid{
public:
// initialize vector with 3 Points with val Points(0)
Grid(vector<Points> v) : v_points(3, Points(0)) {};
private:
vector<Points> v_points;
};
Note, we do it in initialization list. For POD class members, it makes no difference, it's just a matter of style. For class members which are classes, then it avoids an unnecessary call to a default constructor.
Did I initialize constructor correctly and When writing a destructor
for Grid do I need to write a destructor for vector like this:
~vecotr() or with delete or using iterator?
You don't initialize constructor, rather in constructor initializer list you initialize class members. Since vector is not allocated with new, you will not delete it (call delete). It will be destroyed automatically when Grid is destroyed.
// fourth (and correct) option:
~Grid() {
}
Or just leave out the destructor entirely; the compiler-generated destructor will do the right thing here.
If you create an object with new you must delete it. If you don't, you mustn't.
I am assuming that Points does not have any dynamically allocated memory. If this is the case then all you need is
~Grid() { }
If it does then you need to delete that dynamically allocated memory for each item in the vector (or use smart pointers).

Changing an object after pushing its address to a vector

I have a question:
class B : public class A {
public:
vector<int*> vec;
};
class A {
};
vector<A*> vec_a;
vector<B*> vec_b;
if I push back an object of class B into both vectors.
B* b = new B;
vec_a.push_back(b);
vec_b.push_back(b);
then after that, I change something inside the object of class B,
such as:
int* i = ....
vec_b[0].push_back(i);
Does the vec_a change?
I am confused with that since I have checked that when vector push_back, it will only create a copy. But when I checked with the above codes, it changes. Are the two vectors hold a shared memory of object b?
Thanks
Yes, when pushing to a vector a copy is created. However in your case it's a copy of a pointer, not a copy of the actual object.
Your vectors contain pointers to a common object. Therefore anything you change inside that object via a derefence of one of those pointers is reflected in the object that they are pointing to. Adding the pointers to the vectors creates a copy of the pointers themselves, not the object they point to. Had you added a common instance of class B to both vectors, each vector would contain a separate copy of that object. Adding pointers results copies of your original pointer being added to each vector - but both copies will have the same value and that is the memory address of the object they point to.
You're putting a pointer to the same object in both vectors so any change to the object, pointed from an element in vec_a will affect the element in vec_b, too.
Yes. You create only one object, after all. You push pointers. So std::vector copy pointers, but you change memory they point to.
That's why you get your results. I suggest you read a bit more about pointers.
The vector push_back method indeed does create a copy. But since you have specified vector of pointers (to vec_a and vec_b), copying those pointer does not actually change the original object. You would get what you originally expected if you used
vector<A> vec_a;
vector<B> vec_b;
instead, filling those vectors with
B b;
vec_a.push_back(b);
vec_b.push_back(b);
would actually copy the content of b into the vectors. Changing one will not affect the other.

Return vector from function without it being destroyed

I have come across an interesting problem. I have a function in C++ that returns a vector filled with classes. Once the vector is returned, it calls deconstructors for each class that is element in the vector.
The problem is an obvious one: the data is destroyed where a class points to the pointers, which get released when the object is destroyed. I can only assume the deconstructors are called because the vector is on the stack, and not on the heap.
So the question is:
Is there anyway to keep returning vector from a function, without it being destroyed? Or would I have to either pass a pointer to return vector as an input to the function?
You can create anything on heap with new. You shouldn't give out from the function the references to your stack objects, as they will be destroyed as soon as the function finishes.
If you prefer your function to return the vector by value, be sure that the objects inside the vector implement copy constructor (and perhaps assignment operator, too, not sure about that). Having that, please do not forget about the Rule of Three.
C++11 should solve your problem using rvalue references. Honestly, I haven't tried it myself, but from what I read it will do exactly what you are trying to do, return the vector without destroying and recreating it (by passing the memory allocated by that vector on to the new vector instead of having the new vector create its own memory and copy the contents over from the old one).
C++ vectors are allocated on the heap. When you return a vector by value a new one will be created with copies of all the elements, then the original elements will be destroyed.
It sounds like you haven't defined your copy constructors properly. For example:
class ThisIsWrong
{
public:
ThisIsWrong()
{
i = new int;
*i = rand();
}
~ThisIsWrong()
{
delete i;
i = nullptr;
}
int value() const
{
return *i;
}
private:
int* i;
};
void foo()
{
vector<ThisIsWrong> wronglets;
wronglets.push_back(ThisIsWrong());
return wronglets;
}
void main()
{
vector<ThisIsWrong> w = foo();
w[0].value(); // SEGFAULT!!
}
You either need to delete the copy and assignment constructors (which will then turn this into a compilation error instead of runtime), or implement them properly.

Class members that are objects - Pointers or not? C++

If I create a class MyClass and it has some private member say MyOtherClass, is it better to make MyOtherClass a pointer or not? What does it mean also to have it as not a pointer in terms of where it is stored in memory? Will the object be created when the class is created?
I noticed that the examples in QT usually declare class members as pointers when they are classes.
If I create a class MyClass and it has some private member say MyOtherClass, is it better to make MyOtherClass a pointer or not?
you should generally declare it as a value in your class. it will be local, there will be less chance for errors, fewer allocations -- ultimately fewer things that could go wrong, and the compiler can always know it is there at a specified offset so... it helps optimization and binary reduction at a few levels. there will be a few cases where you know you'll have to deal with pointer (i.e. polymorphic, shared, requires reallocation), it is typically best to use a pointer only when necessary - especially when it is private/encapsulated.
What does it mean also to have it as not a pointer in terms of where it is stored in memory?
its address will be close to (or equal to) this -- gcc (for example) has some advanced options to dump class data (sizes, vtables, offsets)
Will the object be created when the class is created?
yes - the size of MyClass will grow by sizeof(MyOtherClass), or more if the compiler realigns it (e.g. to its natural alignment)
Where is your member stored in memory?
Take a look at this example:
struct Foo { int m; };
struct A {
Foo foo;
};
struct B {
Foo *foo;
B() : foo(new Foo()) { } // ctor: allocate Foo on heap
~B() { delete foo; } // dtor: Don't forget this!
};
void bar() {
A a_stack; // a_stack is on stack
// a_stack.foo is on stack too
A* a_heap = new A(); // a_heap is on stack (it's a pointer)
// *a_heap (the pointee) is on heap
// a_heap->foo is on heap
B b_stack; // b_stack is on stack
// b_stack.foo is on stack
// *b_stack.foo is on heap
B* b_heap = new B(); // b_heap is on stack
// *b_heap is on heap
// b_heap->foo is on heap
// *(b_heap->foo is on heap
delete a_heap;
delete b_heap;
// B::~B() will delete b_heap->foo!
}
We define two classes A and B. A stores a public member foo of type Foo. B has a member foo of type pointer to Foo.
What's the situation for A:
If you create a variable a_stack of type A on the stack, then the object (obviously) and its members are on the stack too.
If you create a pointer to A like a_heap in the above example, just the pointer variable is on the stack; everything else (the object and it's members) are on the heap.
What does the situation look like in case of B:
you create B on the stack: then both the object and its member foo are on the stack, but the object that foo points to (the pointee) is on the heap. In short: b_stack.foo (the pointer) is on the stack, but *b_stack.foo the (pointee) is on the heap.
you create a pointer to B named b_heap: b_heap (the pointer) is on the stack, *b_heap (the pointee) is on the heap, as well as the member b_heap->foo and *b_heap->foo.
Will the object be automagically created?
In case of A: Yes, foo will automatically be created by calling the implicit default constructor of Foo. This will create an integer but will not intitialize it (it will have a random number)!
In case of B: If you omit our ctor and dtor then foo (the pointer) will also be created and initialized with a random number which means that it will point to a random location on the heap. But note, that the pointer exists! Note also, that the implicit default constructor won't allocate something for foo for you, you have to do this explicitly. That's why you usually need an explicit constructor and a accompanying destructor to allocate and delete the pointee of your member pointer. Don't forget about copy semantics: what happens to the pointee if your copy the object (via copy construction or assignment)?
What's the point of all of this?
There are several use cases of using a pointer to a member:
To point to an object you don't own. Let's say your class needs access to a huge data structure that is very costly to copy. Then you could just save a pointer to this data structure. Be aware that in this case creation and deletion of the data structure is out of the scope of your class. Someone other has to take care.
Increasing compilation time, since in your header file the pointee does not have to be defined.
A bit more advanced; When your class has a pointer to another class that stores all private members, the "Pimpl idiom": http://c2.com/cgi/wiki?PimplIdiom, take also a look at Sutter, H. (2000): Exceptional C++, p. 99--119
And some others, look at the other answers
Advice
Take extra care if your members are pointers and you own them. You have to write proper constructors, destructors and think about copy constructors and assignment operators. What happens to the pointee if you copy the object? Usually you will have to copy construct the pointee as well!
In C++, pointers are objects in their own right. They're not really tied to whatever they point to, and there's no special interaction between a pointer and its pointee (is that a word?)
If you create a pointer, you create a pointer and nothing else. You don't create the object that it might or might not point to. And when a pointer goes out of scope, the pointed-to object is unaffected. A pointer doesn't in any way affect the lifetime of whatever it points to.
So in general, you should not use pointers by default. If your class contains another object, that other object shouldn't be a pointer.
However, if your class knows about another object, then a pointer might be a good way to represent it (since multiple instances of your class can then point to the same instance, without taking ownership of it, and without controlling its lifetime)
The common wisdom in C++ is to avoid the use of (bare) pointers as much as possible. Especially bare pointers that point to dynamically allocated memory.
The reason is because pointers make it more difficult to write robust classes, especially when you also have to consider the possibility of exceptions being thrown.
I follow the following rule: if the member object lives and dies with the encapsulating object, do not use pointers. You will need a pointer if the member object has to outlive the encapsulating object for some reason. Depends on the task at hand.
Usually you use a pointer if the member object is given to you and not created by you. Then you usually don't have to destroy it either.
This question could be deliberated endlessly, but the basics are:
If MyOtherClass is not a pointer:
The creation and destruction of MyOtherClass is automatic, which can reduce bugs.
The memory used by MyOtherClass is local to the MyClassInstance, which could improve performance.
If MyOtherClass is a pointer:
The creation and destruction of MyOtherClass is your responsibility
MyOtherClass may be NULL, which could have meaning in your context and could save memory
Two instances of MyClass could share the same MyOtherClass
Some advantages of pointer member:
The child (MyOtherClass) object can have different lifetime than its parent (MyClass).
The object can possibly be shared between several MyClass (or other) objects.
When compiling the header file for MyClass, the compiler doesn't necessarily have to know the definition of MyOtherClass. You don't have to include its header, thus decreasing compile times.
Makes MyClass size smaller. This can be important for performance if your code does a lot of copying of MyClass objects. You can just copy the MyOtherClass pointer and implement some kind of reference counting system.
Advantages of having the member as an object:
You don't have to explicitely write code to create and destroy the object. It's easier and and less error-prone.
Makes memory management more efficient because only one block of memory needs to be allocated instead of two.
Implementing assignment operators, copy/move constructors etc is much simpler.
More intuitive
If you make the MyOtherClass object as member of your MyClass:
size of MyClass = size of MyClass + size of MyOtherClass
If you make the MyOtherClass object as pointer member of your MyClass:
size of MyClass = size of MyClass + size of any pointer on your system
You might want to keep MyOtherClass as a pointer member because it gives you the flexibility to point it to any other class that is derived from it. Basically helps you implement dynamice polymorphism.
It depends... :-)
If you use pointers to say a class A, you have to create the object of type A e.g. in the constructor of your class
m_pA = new A();
Moreover, don't forget to destroy the object in the destructor or you have a memory leak:
delete m_pA;
m_pA = NULL;
Instead, having an object of type A aggregated in your class is easier, you can't forget to destroy it, because this is done automatically at the end of lifetime of your object.
On the other hand, having a pointer has the following advantages:
If your object is allocated on the
stack and type A uses a lot of memory
this won't be allocated from the
stack but from the heap.
You can construct your A object later (e.g. in a method Create) or destroy it earlier (in method Close)
An advantage of the parent class maintaining the relation to a member object as a (std::auto_ptr) pointer to the member object is that you can forward declare the object rather than having to include the object's header file.
This decouples the classes at build time allowing to modify the member object's header class without causing all the clients of your parent class to be recompiled as well even though they probably do not access the member object's functions.
When you use an auto_ptr, you only need to take care of construction, which you could typically do in the initializer list. Destruction along with the parent object is guaranteed by the auto_ptr.
The simple thing to do is to declare your members as objects. This way, you do not have to care about copy construction, destruction and assignment. This is all taken care of automatically.
However, there are still some cases when you want pointers. After all, managed languages (like C# or Java) actually hold member objects by pointers.
The most obvious case is when the object to be kept is polymorphic. In Qt, as you pointed out, most objects belong to a huge hierarchy of polymorphic classes, and holding them by pointers is mandatory since you don't know at advance what size will the member object have.
Please beware of some common pitfalls in this case, especially when you deal with generic classes. Exception safety is a big concern:
struct Foo
{
Foo()
{
bar_ = new Bar();
baz_ = new Baz(); // If this line throw, bar_ is never reclaimed
// See copy constructor for a workaround
}
Foo(Foo const& x)
{
bar_ = x.bar_.clone();
try { baz_ = x.baz_.clone(); }
catch (...) { delete bar_; throw; }
}
// Copy and swap idiom is perfect for this.
// It yields exception safe operator= if the copy constructor
// is exception safe.
void swap(Foo& x) throw()
{ std::swap(bar_, x.bar_); std::swap(baz_, x.baz_); }
Foo& operator=(Foo x) { x.swap(*this); return *this; }
private:
Bar* bar_;
Baz* baz_;
};
As you see, it is quite cumbersome to have exception safe constructors in the presence of pointers. You should look at RAII and smart pointers (there are plenty of resources here and somewhere else on the web).