Storing objects using std::vector

I have two classes, Parent and Child, where Parent contains a vector that is used to store instances of Child. When I create an instance of Parent, three instances of Child are also created in Parent's constructor and stored in the vector. I understand that push_back() creates a shallow copy of each Child instance and that Child's destructor is called each time the loop (inside Parent's constructor) iterates. The problem is that because Child's destructor is called each time the local variable child goes out of scope, the memory previously allocated in Child's constructor is destroyed and when Child's destructor is called again later on in the program to get rid of the copy stored in vector, the program crashes. I can fix this by overriding the default copy function or by storing pointers to objects instead of copies of objects. I was wondering if there is a more 'elegant' way of solving this problem? I don't really need to use vectors in this case since I always have three children in one parent but I'm doing this as a learning exercise and would prefer to use vectors.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <vector>

class Child {
public:
	Child() {
		std::cout << "child constructor called" << std::endl;
		i_ptr = new int[10];
	}

	~Child() {
		std::cout << "child destructor called" << std::endl;
		delete[] i_ptr;
	}

private:
	int *i_ptr;
};

class Parent {

public:
	Parent() {
		child_list.reserve(10);

		for (int i = 0; i < 3; i++) {
			Child child;
			child_list.push_back(child);
		}
	}

	~Parent() { }

private:
	std::vector<Child> child_list;
};

int main(int argc, char *argv[]) {
	Parent parent;
	return 0;
}
Possible ideas:

1. Add a copy constructor to the Child class that does a deep copy.
2. Replace the array of ints with a std::vector<int>
3. If you are using C++11, use emplace_back
http://www.cplusplus.com/reference/vector/vector/emplace_back/
Last edited on
The problem with emplace_back is that the program will still crash when I try to add the 11th instance of child into the vector. It'll call the copy constructor of each object and destroy old instances (and deallocate the memory). I suppose my only possible solution is overriding the copy constructor.
Huh?

From the above-referenced web page:

Inserts a new element at the end of the vector, right after its current last element. This new element is constructed in place using args as the arguments for its constructor.

This effectively increases the container size by one, which causes an automatic reallocation of the allocated storage space if -and only if- the new vector size surpasses the current vector capacity.

The element is constructed in-place by calling allocator_traits::construct with args forwarded.

A similar member function exists, push_back, which either copies or moves an existing object into the container.


Why would the program crash when you add the 11th member to a dynamic data structure?

Edit: The rule of 3 (now the rule of 5) says if you write a destructor, you need to write a copy constructor and an assignment operator. So you need to be writing a copy constructor anyway.
Last edited on
Topic archived. No new replies allowed.