The vector template is defined in header file <vector>. Like all other standard library components, it resides in namespace std. The interface emulates the behavior of a C array (i.e., capable of fast random access) but with the additional ability to automatically resize itself when inserting or removing an object. The vector template can be instantiated with any type that fulfills the CopyConstructible and Assignable requirements:[1] expression return type requirement T& t is equivalent to u n/a t is equivalent to T(t) n/a u is equivalent to T(u) (const) T* denotes the address of u n/a n/a t = u T(t) T(u) &u t.~T() Where T is the type used to instantiate the vector, t is a value of T and u is a value of (possibly const) T. For a given vector all elements must belong to the same type. For instance, one cannot store data in the form of both char and int within the same vector instance. Vectors provide a standard set of functions for accessing elements, adding elements to the end or anywhere, deleting elements and finding how many elements are stored. [edit] Individual element access Individual elements of a vector can be accessed using the operation shown in the table below. Following the standard convention for C and C++, the first element has index 0, and the last element has index size() - 1[2]. expression v.at(i) T& or const v[i] T& or const v.front() T& or const v.back() T& or const return type bounds checking? T& to the element at index i yes, throws out_of_range exception[2][3] T& to the element at index i undefined behaviour if i >= v.size() T& to the first element undefined behaviour if v.empty() is true T& to the last element undefined behaviour if v.empty() is true Where v is an object of type (possibly const) vector<T> and i represents the index. [edit] Overview of functions The vector class models the Container concept, which means it has begin(), end(), size(), max_size(), empty(), and swap() methods. informative o o o o o vector::front - Returns reference to first element of vector. vector::back - Returns reference to last element of vector. vector::size - Returns number of elements in the vector. vector::empty - Returns true if vector has no elements. vector::capacity - Returns current capacity (allocated memory) standard operations of vector. o vector::insert - Inserts elements into a vector (single & range), shifts later elements up. O(n) time. o vector::push_back - Appends (inserts) an element to the end of a vector, allocating memory for it if necessary. Amortized O(1) time. o vector::erase - Deletes elements from a vector (single & range), shifts later elements down. O(n) time. o vector::pop_back - Erases the last element of the vector, O(1) time. Does not usually reduce the memory overhead of the vector. Amortized O(1) time. o vector::clear - Erases all of the elements. (This does not reduce capacity) allocation/size modification o vector::reserve - Changes capacity (allocates more memory) of the vector, if needed. In many STL implementations capacity can only grow, and is never reduced. O(n) if the vector expands. O(1) if not. o vector::resize - Changes the vector size. O(n) time. iteration o vector::begin - Returns an iterator to start traversal of the vector. o vector::end - Returns an iterator that points just beyond the end of the vector. [edit] Vector iterators In addition to the direct element access functions outlined above, the elements of a vector can be accessed through vector iterators. [edit] Capacity and reallocation A typical vector implementation consists, internally, of a pointer to a dynamically allocated array,[2] and possibly data members holding the capacity and size of the vector. The size of the vector refers to the actual number of elements, while the capacity refers to the size of the internal array. When new elements are inserted, if the new size of the vector becomes larger than its capacity, reallocation occurs.[2][4] This typically causes the vector to allocate a new region of storage, move the previously held elements to the new region of storage, and free the old region. Because the addresses of the elements change during this process, any references or iterators to elements in the vector become invalidated.[5] Using an invalidated reference causes undefined behaviour. Example: #include <vector> int main() { std::vector<int> v(1); // create a vector holding a single int with value 0. int& first = *v.begin(); // make a reference to the first element v.insert(v.end(), v.capacity(), 0); // append more elements to the vector, forcing a reallocation int i = first; // undefined behaviour; the reference has been invalidated } The reserve() operation may be used to prevent unnecessary reallocations. After a call to reserve(n), the vector's capacity is guaranteed to be at least n.[6] Example: #include <vector> int main() { std::vector<int> v(1); // create a vector holding a single int with value 0. v.reserve(10); // reserve space to prevent reallocation int& first = *v.begin(); // make a reference to the first element v.insert(v.end(), 5, 0); // append more elements to the vector int i = first; // OK, no reallocation has occurred } The vector maintains a certain order of its elements, so that when a new element is inserted at the beginning or in the middle of the vector, subsequent elements are moved backwards in terms of their assignment operator or copy constructor. Consequently, references and iterators to elements behind the insertion point becomes invalidated.[7] Example: #include <vector> int main() { std::vector<int> v(2); // constructs a vector holding two ints // make references to the two ints int& first = v.front(); int& last = v.back(); v.insert(v.begin() + 1, 1, 1); // insert a new int in the middle of the vector. int i = first; // undefined behaviour if the previous insert caused reallocation int j = last; // undefined behaviour per the C++ standard, §23.2.4.3/1 } [edit] vector<bool> specialization The Standard Library defines a specialization of the vector template for bool. The description of this specialization indicates that the implementation should pack the elements so that every bool only uses one bit of memory.[8] This is widely considered a mistake.[9][10] vector<bool> does not meet the requirements for a C++ Standard Library container. For instance, a container<T>::reference must be a true lvalue of type T. This is not the case with vector<bool>::reference, which is a proxy class convertible to bool.[11] Similarly, the vector<bool>::iterator does not yield a bool& when dereferenced. There is a general consensus among the C++ Standard Committee and the Library Working Group that vector<bool> should be deprecated and subsequently removed from the standard library, while the functionality will be reintroduced under a different name.[12] This change is unlikely to take place until after C++0x. [edit] Usage A C++ program that is to use vectors must #include <vector>. A vector is declared using: std::vector<T> instance; where "T" is the data type the vector is to store, and "instance" is the variable name of the vector. T can be any Assignable type, including user-defined types. An alternative to storing objects of type T is to store objects of type T*. This is useful if T is not Assignable, or is expensive to copy.[13] [edit] Replacement for arrays In C++, arrays are contiguous pieces of memory. They are somewhat like blocks aligned together, each block is then given a number, and to look at the contents of each block one only has to supply the number of the block. All the elements of an array must be of the same type. A vector is similar to a dynamically allocated array but with the ability to resize itself, and without the need for manual deallocation of memory. Because the elements of a vector are stored contiguously,[14] the address of the first element of a vector can be passed to functions expecting an array (a pointer to the first element). The following example shows how a vector can be used with the C Standard Library functions memcpy and printf: #include <cstring> // memcpy #include <vector> #include <cstdio> // printf int main() { using namespace std; const char arr[] = "1234567890"; // construct a vector with 11 zero-initialized chars. vector<char> vec(sizeof arr); // copy 11 chars from arr into the vector memcpy(&vec[0], arr, sizeof arr); // prints "1234567890" printf("%s", &vec[0]); } Note that such use of memcpy and printf is generally discouraged in favour of type safe alternatives from the C++ Standard Library.[15] [edit] Usage example The following example demonstrates various techniques involving a vector and C++ Standard Library algorithms, notably shuffling, sorting, finding the largest element, and erasing from a vector using the eraseremove idiom. #include <iostream> #include <vector> #include <algorithm> // sort, max_element, random_shuffle, remove_if, lower_bound #include <functional> // greater, bind2nd // used here for convenience, use judiciously in real programs. using namespace std; int main() { int arr[4] = {1, 2, 3, 4}; // initialize a vector from an array vector<int> numbers(arr, arr+4); // insert more numbers into the vector numbers.push_back(5); numbers.push_back(6); numbers.push_back(7); numbers.push_back(8); // the vector currently holds {1, 2, 3, 4, 5, 6, 7, 8} // randomly shuffle the elements random_shuffle( numbers.begin(), numbers.end() ); // locate the largest element, O(n) vector<int>::const_iterator largest = max_element( numbers.begin(), numbers.end() ); cout << "The largest number is " << *largest << "\n"; cout << "It is located at index " << largest - numbers.begin() << "\n"; // sort the elements sort( numbers.begin(), numbers.end() ); // find the position of the number 5 in the vector, O(log n) vector<int>::const_iterator five = lower_bound( numbers.begin(), numbers.end(), 5 ); cout << "The number 5 is located at index " << five - numbers.begin() << "\n"; // erase all the elements greater than 4 numbers.erase( remove_if(numbers.begin(), numbers.end(), bind2nd(greater<int>(), 4) ), numbers.end() ); // print all the remaining numbers for(vector<int>::const_iterator it = numbers.begin(); it != numbers.end(); ++it) { cout << *it << " "; } return 0; } The output will be the following: The largest number is 8 It is located at index 6 (implementation-dependent) The number 5 is located at index 4 1234 Example of 2 dimensional dynamic vector array, and accessing and modifying it: typedef std::vector< std::vector<int> > pxMP; void function() { int sizeX, sizeY; // size can be set on-the-fly. pxMP pxMap(sizeX, std::vector<int>(sizeY)); // X/Y array of pixels 0,1. pxMap[0][5] = 1; /* accessing it */ // delete left and right columns: pxMap.pop_back(); pxMap.erase(pxMap.begin()); // delete top and bottom rows of all columns, first make some tools: std::vector< std::vector<int> >::iterator iterlvl2; // iterator level 2 dimension. std::vector< int >::iterator iterlvl1; // iterator level 1 dimension // lets' go deeper. We must go deeper. for (iterlvl2=pxMap.begin();iterlvl2 != pxMap.end();iterlvl2++) { iterlvl1 = (*iterlvl2).begin(); // demo purpose only. so beautiful. access granted, I N C E P T I O N. (*iterlvl2).pop_back(); (*iterlvl2).erase((*iterlvl2).begin()); // where are we? sizeY = (*iterlvl2).size(); // set new sizeY while on this level, once we return to the higher level we cannot retrieve... } /* that was cool */ } [edit] Vector visualization Semantically picturing the vector push_back( data ) operation. Note the size of the vector increases from 6 to 7 after the operation. Semantically picturing the vector pop_back() operation. Note the size of the vector decreases from 7 to 6 after the operation. Semantically picturing the vector resize( int ) operation. Note the size of the vector increases to 9, and the new elements are filled with a default value. [edit] Pros and cons Like all dynamic array implementations, vectors have low memory usage and good locality of reference and data cache utilization. The vector data structure is able to quickly and easily allocate the necessary memory needed for specific data storage. This is particularly useful for storing data in lists whose length may not be known prior to setting up the list but where removal (other than, perhaps, at the end) is rare. Like other STL containers, vectors may contain both primitive data types and complex, user-defined classes or structs. Unlike other STL containers, such as deques and lists, vectors allow the user to denote an initial capacity for the container. Vectors allow random access; that is, an element of a vector may be referenced in the same manner as elements of arrays (by array indices). Linked-lists and sets, on the other hand, do not support random access or pointer arithmetic. Erasing elements from a vector or even clearing the vector entirely does not necessarily free any of the memory associated with that element. This is because the maximum size of a vector since its creation is a good estimate of the future size of the vector. Vectors are inefficient at removing or inserting elements other than at the end. Such operations have O(n) (see Big-O notation) complexity compared with O(1) for linked-lists. This is offset by the speed of access - access to a random element in a vector is of complexity O(1) compared with O(n) for general linked-lists and O(log n) for link-trees. C++ vectors do not support in-place reallocation of memory, by design; i.e., upon reallocation of a vector, the memory it held will always be copied to a new block of memory using its elements' copy constructor, and then released. This is inefficient for cases where the vector holds plain old data and additional contiguous space beyond the held block of memory is available for allocation.