The internal implementation of vector is actually a piece of continuous memory, which is different from the traditional array, supports expansion, do not consider cross-border. The vector iterator is the simplest pointer to the type in the container. There are three internal pointers: Start (pointing to the first address of the data storage area), finish (the end of the used data area), end_of_storage (pointing to the end of the capacity, the capacity is generally surplus ), in case of full load, the finish pointer is equal to the end_of_storage pointer, that is, when the capacity is used up, if the element is inserted, it will be expanded.
When resizing is required, the space adapter will find a larger memory space (because a continuous memory is inside the vector), and then start points to the first address of the new memory and copies the original data, insert new data and update finish and end_of_storage at the same time. Generally, the scale is twice the original capacity.
The following code refers to the fourth chapter of Hou Jie's STL source code analysis. It is intended to understand the memory management of vector and the implementation of each interface. For the sake of simplicity, some interfaces are not implemented in accordance with the standard. I manually implemented some space adapters and did not make them public interfaces any more. Instead, they are directly added to the function implementation, it may be rough.
# Include <iostream> using namespace STD; Template <class T> class myvector {public: typedef T * iterator; typedef T * pointer; typedef T & reference; myvector (): start (0), finish (0), end_of_storage (0) {} myvector (int n, const reference Val) // apply for N Units of space, use Val to initialize {start = new T [N]; finish = start; end_of_storage = start + N; while (n --) {* Finish ++ = Val ;}} myvector (int n) // apply for N Units of space, initialized to 0 {start = new T [N]; finish = start; end_o F_storage = start + N; while (n --) {* Finish ++ = 0 ;}}~ Myvector () {iterator I; for (I = start; I <end_of_storage; I ++) I-> ~ T ();} iterator begin () const {return start;} iterator end () const {return finish;} // pay attention to the definition of size. The returned value is end-begin, that is, finish points to the address int size () const {return int (end ()-begin () ;}// void resize (INT new_size, const reference X); // redefine the space size and complete initialization. The finish pointer is at the end of the Space // void resize (INT new_size); // void reserve (INT new_size ); // redefines the space size, but does not change the finish pointer int capacity () const {return end_of_storage-begin ();} Bool empty () const {return begin () = end ();} reference operator [] (int n) {return * (begin () + n );} reference Front () {return * begin ();} reference back () {return * (end ()-1);} void push_back (const reference X) {If (finish! = End_of_storage) // not fully loaded {* Finish = x; finish ++;} else insert (end (), 1, x); // fully loaded, need to be reassigned, and complete the migration of existing members} void pop_back () // delete the end element {finish --; finish-> ~ T ();} void erase (iterator first, iterator last) // clear all elements of [first, last) {Int J = end ()-last; for (INT I = 0; I <j; I ++) {* (first + I) = * (last + I) ;}while (end ()> first + J) {pop_back () ;}} void erase (iterator position) // clear the specified position element {erase (Position, Position + 1);} void clear () {// clear vectorerase (begin (), end ();} void insert (iterator position, int N, const reference X); // insert n elements from position, the initial value of each element is X // void insert_aux (iterator position, c Onst reference X); // re-allocate the space and complete the migration of existing members PRIVATE: iterator start; iterator finish; iterator end_of_storage ;}; template <class T> void myvector <t>: insert (iterator position, int N, const reference X) // insert n elements from position, the initial value of each element is X {/* STL vector <class type>: insert (type *, Int, const type &). function: insert an element at a specified position, expansion may occur. When the insert result shows that the finish pointer is greater than end_ofstorage, You need to resize */iterator I = start; // old_startiterator new_finish; // if not, point to O. Ld_start: new_startiterator old_start = start, old_finish = finish; bool needtodestory = false; If (finish + n> end_of_storage) {needtodestory = true; const int old_size = size (); const int Len = old_size + N; Start = new T [Len]; new_finish = start; end_of_storage = start + Len;} else {new_finish = start; end_of_storage = finish + N ;} /* original data migration */while (I <position) {* new_finish ++ = * I ++;}/* initialize the inserted part */while (N --) {* new_finish ++ = x;}/* migration of raw data */while (I <finish) {* new_finish ++ = * I ++ ;} finish = new_finish;/* The original space needs to be released here */If (needtodestory = true) {While (old_start! = Old_finish) {old_start-> ~ T (); old_start ++ }}/ * template <class T> void myvector <t>: insert_aux (iterator position, const reference X) {insert (position, 1, x); // re-allocate the space and complete the migration of existing members} */struct node {node () {} node (int A = 0, int B = 0): X (A), y (B) {}int X, Y ;}; int main () {myvector <node> test (3 ); cout <"size of vector now:" <test. size () <"\ t" <"Capacity of vector now:" <test. capacity () <Endl; For (INT I = 0; I <3; I ++) {node A (I, I * I); test. push_ba CK (a);/* push_back () is inserted from the end () end, and the end () of the initialized vector is equal to capacity (), so resizing occurs, that is to say, the positions of the three points (), (), () We insert are in a [3], a [4], a [5, in a [0], a [1], a [2], it is still the initial value. If you think this is a waste of time and want to insert the vertex to the initial position, there are several methods: node 1: When you can apply for a container again, the size is not specified (the default value is 0), so subsequent insertion Causes expansion, naturally, node 2 starts from the first position (a [0]): specify the size with reserve (N). This function will not modify the finish pointer, that is, the finish Pointer Points to the begin () end PS: Reserve () interface, which I have not implemented here. Leave it to a later time plus Node 3: Use Insert () to insert points at the specified position, but this will cause node resizing ...... Welcome to supplement pai_^ */} cout <"size of vector now:" <test. size () <"\ t" <"Capacity of vector now:" <test. capacity () <Endl; myvector <node>: iterator PI; For (Pi = test. begin (); Pi! = Test. end (); Pi ++) {cout <pi-> x <"" <pi-> Y <Endl ;} /****** test insert () *******/test. insert (test. begin (), 7, test [5]); // insert seven elements at the begin () end, And the size is changed to size () + 7 cout <"size of vector now: "<test. size () <"\ t" <"Capacity of vector now:" <test. capacity () <Endl; myvector <node>: iterator PJ; For (PJ = test. begin (); PJ! = Test. End (); PJ ++) {cout <PJ-> x <"" <PJ-> Y <Endl;} return 0 ;}