Accelerated C++ Solution to Exercise 6-3

Exercise 6-3

What does this program fragment do?

vector<int> u(10, 100)
vector<int> v;
copy(u.begin(), u.end(), v.begin());

Solution

Let’s look at the 3 lines one-by-one.

The First Line

Starting with the first line:

vector<int> u(10, 100);

This statement creates a vector<int> container named u. It allocates system memory and give the container a size of 10 as defined by the first argument (i.e. having the ability to store 10 int elements), and immediately create 10 int elements each has an initial value of 100, as defined by the second argument. i.e. We expect u to contains 10 int elements, each has a value of 100.

I can test this out easily via a simple program like this:

#include <iostream>     // cout, endl
#include <vector>       // vector

using std::vector;
using std::cout;
using std::endl;

int main()
{
  vector<int> u(10, 100);

  for (vector<int>::const_iterator i = u.begin(); i != u.end(); ++i)
    cout << (*i) << endl;

  return 0;
}

Running this program gives the followings as expected.

100
100
100
100
100
100
100
100
100
100

Note that if I change the statement slightly to instead:

vector<int> u(10);

This statement would create 10 elements for u with the default initial value of 0 (determined by the <int> part).

The Second Line

This second line is very easy:

vector<int> v;

This statement creates a vector<int> container v with no elements (and a size of zero).

The Third Line

Now the third line:

copy(u.begin(), u.end(), v.begin());

Though at first sight this statement appears to copy all the elements from the vector<int> container u, to the beginning of the empty vector<int> container v, this line will crash the program. Why? Because v initially has zero elements and has a container size of zero. In order to copy additional elements to this empty container v, we must first have a means to grow the container size dynamically by using utilities like back_inserter or inserter (page 121 of the book). In fact, in the next Exercise we shall correct this program using these utilities.

For now, let me illustrate that running the following program as it is will indeed crash the system:

#include <iostream>     // cout, endl
#include <vector>       // vector
#include <algorithm>    // copy

using std::vector;
using std::cout;
using std::endl;

int main()
{
  vector<int> u(10, 100);

  cout << "vector<int> u looks like this:" << endl;
  for (vector<int>::const_iterator i = u.begin(); i != u.end(); ++i)
    cout << (*i) << endl;

  vector<int> v;
  //copy(u.begin(), u.end(), v.begin());  // program crashes!

  cout << "vector<int> v looks like this:" << endl;
  for (vector<int>::const_iterator i = v.begin(); i != v.end(); ++i)
    cout << (*i) << endl;

  return 0;
}

Program crashes! (on my Vista system it gives a return code of -1073741819 (0xC0000005) )

Acpp6p3Pic1

Conclusion

This exercises illustrates that in order for the copy function to work, we must have a means to grow the vector dynamically, such as using the utilities back_inserter or inserter, as we shall see in my Solution to Exercise 6-4.

Reference

Koenig, Andrew & Moo, Barbara E., Accelerated C++, Addison-Wesley, 2000