Standard Template Libraries: Using std::vector Arrays

Environment: VC5, VC6, VC7.NET, WinXP, Win2000, Win98, NT4 SP3

What Is the std::vector Array?

The vector array is part of the

standard namespace (std::); it allows you to easily create a

dynamic array of elements. The vector class belongs to the STL (

Standard Template Libraries ) and is a template class in itself; this means that we can create an array of almost any data-type or object within our programs when using it. The

vector class handles most of the memory management for you.

When Might You Use a Vector Array?

A vector array would be ideal in a situation where you need to store dynamic data; for example, an array that changes in size during the program’s execution.

How Do You Use the Vector Array?

To use the vector array, you first will need to include the <vector> header file. In older versions of Microsoft Visual C++ (2002 and below), you can either include the <vector> header or the <vector.h> header; the <vector.h> header was removed in Microsoft Visual C++ 7.1 (2003).

Then, you will need to actually create your array. Here is an example of the declaration of an array of integers:

// VectorTest.cpp
//

// files to include
#include <stdio.h>      // standard input/output
#include <vector>       // stl vector header

using namespace std;    // saves us typing std:: before vector

void main()
{
  // create an array of integers
  vector<int> arNumbers;
}

Notice that, when declaring an array of integers, we first type

vector , which as with the use of any class, indicates that we want to create an object of that type. We then place the data-type “int” within sharp brackets to indicate that we want to create an array of integers. When creating template classes, a very important factor is being able to specify additional information to the class; this information is specified within the sharp brackets. Then, we simply state the name (arNumbers) we want to give our array and terminate the statement with a semicolon.

Then, to add elements to this array, we call the vectors “push_back” member function; this basically appends a new element of the data-type originally specified (in this case “int”) to the end of the array. Here is an example where we add four elements to our array:

// same as in previous code sample above

void main()
{
  // create an array of integers
  vector<int> arNumbers;

  // add four elements to our array
  arNumbers.push_back(12);
  arNumbers.push_back(24);
  arNumbers.push_back(36);
  arNumbers.push_back(48);
}

It then is possible to retrieve this information again by using a very similar method to that used with standard arrays. The following code sample extends the previous section beneath the line “arNumbers.push_back(48);”:

  // get the total amount of elements within the array
  int nArraySize = (int)arNumbers.size();

  // display the total amount of elements on the screen
  printf("Total Elements: %dnn", nArraySize);

  // display the array's contents on the screen
  for(int i = 0; i < nArraySize; i++)
    printf("Value at position %d is %dn", i, arNumbers[i]);
}

First of all, I have found out the total amount of elements within our vector array; this was done by calling the size() function. Here we also have added a typecast of an integer; this has been done to prevent the compiler from giving us a warning. I then have added a line of code that basically displays the total amount of elements within the array. We have then got a loop that iterates through all of the elements within the array. As with the standard static arrays, it is possible to use the ‘[‘ and ‘]’ operators to access an element at a specific position.

Using the Vector Classes Iterators

The vector class has its own

specialized

iterators that can be used to access information in the array. Many of the vector classes’ member functions require you to input one of these iterators, an example of a function that uses iterators is the erase() function. The erase() function is used to remove one or more elements from the array.

To declare an iterator that is compatible with your vector array, you will need to do something like the following:

vector<int>::iterator NumIt

An iterator is basically like a pointer to the position in memory where the data within the array is stored. To access the value at a given reference, you will need to use the asterisk symbol to dereference the pointer. Here is an example of using these iterators within vector arrays:

// VectorTest.cpp
//

// files to include
#include <stdio.h>      // standard input/output
#include <vector>       // stl vector header

using namespace std;    // saves us typing std:: before vector

void main()
{
  // create an array of integers
  vector<int> arNumbers;

  // add four elements to our array
  arNumbers.push_back(12);
  arNumbers.push_back(24);
  arNumbers.push_back(36);
  arNumbers.push_back(48);

  // get the total amount of elements within the array
  int nArraySize = (int)arNumbers.size();

  // display the total amount of elements on the screen
  printf("Total Elements: %dnn", nArraySize);

  // create a vector<int>::iterator and set the position to which
  // it points to the beginning of the vector array in memory
  vector<int>::iterator itNum = arNumbers.begin();

  // Now, we iterate through the array until the iterator exceeds
  // the end of the array. You will notice that in this for loop
  // I have left out the initialisation section; this is
  // because it has been done separatly before.
  for(; itNum < arNumbers.end(); itNum++)
    printf("Value at position %d is %dn",
      (int)(itNum - arNumbers.begin()), *itNum);
}

In this scenario, we have calculated the position of each element within the array simply by taking the beginning of the array from the current iterator. So basically, we find how far away from the beginning of the array we are from the current iterator, which is clearly the same value as the index position as within the previous example.

So, now we are going to extend our knowledge by removing the second element of the array (this will be done before the code displaying the contents of the array so that you can see what is happening).

// VectorTest.cpp
//

// files to include
#include <stdio.h>      // standard input/output
#include <vector>       // stl vector header

using namespace std;    // saves us typing std:: before vector

void main()
{
  // create an array of integers
  vector<int> arNumbers;

  // add four elements to our array
  arNumbers.push_back(12);
  arNumbers.push_back(24);
  arNumbers.push_back(36);
  arNumbers.push_back(48);

  // remove the second element from the array, what we say
  // looks like element 1, but because we start counting from
  // 0 it is actually element 2 because 0 represents element 1
  vector<int>::iterator itRemove = arNumbers.begin() + 1;
  // now, actually remove this element from the array
  arNumbers.erase(itRemove);

  // get the total amount of elements within the array
  int nArraySize = (int)arNumbers.size();
  // display the total amount of elements on the screen
  printf("Total Elements: %dnn", nArraySize);

  // get an iterator to the start of the numbers array
  vector<int>::iterator itNum = arNumbers.begin();

  // display the arrays' contents
  for(; itNum < arNumbers.end(); itNum++)
    printf("Value at position %d is %dn",
      (int)(itNum - arNumbers.begin()), *itNum);
}

/* Program's Output:
   ================

   Total Elements: 3

   Value at position 0 is 12
   Value at position 1 is 36
   Value at position 2 is 48
   Press any key to continue

*/

It is also possible to remove a whole range of elements simply by specifying a starting iterator and an ending iterator, as in the following:

arNumbers.erase(itStart, itEnd);

Clearing the Entire Vector Array

The clear() member function of the vector array can be used to clear all of the elements from the array. Be aware, if the array contained points to memory that was created dynamically, i.e. the new operator was used, the memory will not be freed, therefore causing a memory leak. So, you would need to make sure that you called the delete operator for each element within the array before calling the clear() function. Here is an example:

// same as before

class CMyClass
{
public:
  CMyClass() {}
  CMyClass(int def_x, int def_y) : x(def_x), y(def_y) {}
  virtual ~CMyClass() {}

  // this classes member functions
  // ...

  // some data (i.e. x and y)...
  int x, y;
};

void main()
{
  // create an array of CMyClass object pointers
  vector<CMyClass*> arMyClass;

  // dynamically add some elements (use new operator)
  arMyClass.push_back(new CMyClass(2, 40));
  arMyClass.push_back(new CMyClass(4, 60));
  arMyClass.push_back(new CMyClass(6, 80));
  arMyClass.push_back(new CMyClass(8, 100));

  // remove the second element from the array
  vector<CMyClass*>::iterator itSecond = arMyClass.begin() + 1;
  delete *itSecond;             // free the memory
  arMyClass.erase(itSecond);    // remove from
                                // the array

  // retrieve the value stored within the first x and y variables
  vector<CMyClass*>::iterator itFirst = arMyClass.begin()/* + 0 */;
  printf("First Coordinate: (%d, %d)n", (*itFirst)->x,
                                         (*itFirst)->y);

  // start from the beginning of the array
  vector<CMyClass*>::iterator itPos = arMyClass.begin();
  // clear all elements from the array
  for(; itPos < arMyClass.end(); itPos++)
    delete *itPos;    // free the element from memory
   // finally, clear all elements from the array
  arMyClass.clear();
}

It can be argued that it is much more efficient to create all elements dynamically (with the new operator) because when iterating through the vector array, the computer will only be iterating through the size of a pointer (usually between 2 and 4 bits of memory) as opposed to iterating through very large objects. This is only really essential for software that needs to run very fast, i.e. games or real-time software. Remember that you will not need to free the memory (i.e. use the delete operator) if you have not dynamically allocated the memory (i.e. used the new operator). If you are simply storing a vector array of pointers to memory that is either static or cleaned up at a later stage, dynamically freeing the memory will not be an issue for you.

If you need to perform large tasks with a vector array, it might be a good idea if you create a class that holds the vector array, but handles the processes that you might wish to perform on the array.

Conclusion

This article just poses as a means for you to get started with std::vector arrays; with practice, you will discover all sorts of different shortcuts and techniques that are available to you. There are also many different STL functions available that allow you to sort the arrays and so forth.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read