vector

array 是C++自带的

array是静态空间,一旦配置了就不能改变;如果要换个大的空间,就要由客户自己来完成:重新申请新空间,然后将元素都从旧地址搬移到新地址,再将原空间释放。

vector是动态空间,随着元素加入,其内部机制会自动扩充空间以容纳新元素。

看看vector的构造函数及析构函数

 // 默认构造出的vector不分配内存空间  
    vector() : start(0), finish(0), end_of_storage(0) {}  
    vector(size_type n, const T& value) { fill_initialize(n, value); }  
    vector(int n, const T& value) { fill_initialize(n, value); }  
    vector(long n, const T& value) { fill_initialize(n, value); }  
    // 需要对象提供默认构造函数  
    explicit vector(size_type n) { fill_initialize(n, T()); }  
    vector(const vector<T, Alloc>& x)  
    {  
        start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end());  
        finish = start + (x.end() - x.begin());  
        end_of_storage = finish;  
    }  

void fill_initialize(size_type n, const T& value)  
    {  
        start = allocate_and_fill(n, value);  
        finish = start + n;                         // 设置当前使用内存空间的结束点  
        // 构造阶段, 此时不多分配内存,分配的空间就是size_type n个  
        // 所以要设置内存空间结束点和 已经使用的内存空间结束点相同  
        end_of_storage = finish;  
    }  

iterator allocate_and_fill(size_type n, const T& x)  
    {  
        iterator result = data_allocator::allocate(n);  
        uninitialized_fill_n(result, n, x);  
        return result;  
    }  


~vector()  
    {  
        destroy(start, finish);    //析构对象  
        deallocate();              //释放内存  
    }  


void deallocate()  
    {  
        // 由于使用的是data_allocator进行内存空间的分配,  
        // 所以需要同样使用data_allocator::deallocate()进行释放  
        // 如果直接释放, 对于data_allocator内部使用内存池的版本  
        // 就会发生错误  
        if (start)  
            data_allocator::deallocate(start, end_of_storage - start);  
    }  

insert()或者push_back()当元素的内存不足时都有内部函数insert_aux()实现,它能实现vector内存不足时,扩大内存至2倍并且把原来的元素移至新地方,同时销毁原来的内存

template <class T, class Alloc>  
    void insert_aux(iterator position, const T& x)  
    {  
        if (finish != end_of_storage)    // 还有备用空间  
        {  
            // 在备用空间起始处构造一个元素,并以vector最后一个元素值为其初值  
            construct(finish, *(finish - 1));  
            ++finish;  
            T x_copy = x;  
            copy_backward(position, finish - 2, finish - 1);  
            *position = x_copy;  
        }  
        else   // 已无备用空间  
        {  
            const size_type old_size = size();  
            const size_type len = old_size != 0 ? 2 * old_size : 1;  
            // 以上配置元素:如果大小为0,则配置1(个元素大小)  
            // 如果原大小不为0,则配置原来大小的两倍  
            // 前半段用来放置原数据,后半段准备用来放置新数据  
  
            iterator new_start = data_allocator::allocate(len);  // 实际配置  
            iterator new_finish = new_start;  
            // 将内存重新配置  
            try  
            {  
                // 将原vector的安插点以前的内容拷贝到新vector  
                new_finish = uninitialized_copy(start, position, new_start);  
                construct(new_finish, x);  //为新元素设定初值x  
                ++new_finish;              //调整水位  
                // 将安插点以后的原内容也拷贝过来  
                new_finish = uninitialized_copy(position, finish, new_finish);  
            }  
            catch(...)  
            {  
                // 回滚操作  
                destroy(new_start, new_finish);  
                data_allocator::deallocate(new_start, len);  
                throw;  
            }  
            // 析构并释放原vector  
            destroy(begin(), end());  
            deallocate();  
  
            // 调整迭代器,指向新vector  
            start = new_start;  
            finish = new_finish;  
            end_of_storage = new_start + len;  
        }  
    }  

注意重新分配内存时原来的迭代器都会失效!!!

template <class T, class Alloc>  
    void insert(iterator position, size_type n, const T& x)  
    {  
        if (n != 0)     //当n不等于0才进行所有操作  
        {  
            if (size_type(end_of_storage - finish) >= n)  
            {      // 剩下的备用空间大于等于“新增元素的个数”  
                T x_copy = x;  
                // 以下计算插入点之后的现有元素个数  
                const size_type elems_after = finish - position;  
                iterator old_finish = finish;  
                if (elems_after > n)  
                {  
                    // 插入点之后的现有元素个数 大于 新增元素个数  
                    //也就是在原来容器的空间够用  
                    uninitialized_copy(finish - n, finish, finish);  
                    finish += n;    // 将vector 尾端标记后移  
                    copy_backward(position, old_finish - n, old_finish);  
                    fill(position, position + n, x_copy); // 从插入点开始填入新值  
                }  
                else  
                {  
                    // 插入点之后的现有元素个数 小于等于 新增元素个数  
                    uninitialized_fill_n(finish, n - elems_after, x_copy);  
                    finish += n - elems_after;  
                    uninitialized_copy(position, old_finish, finish);  
                    finish += elems_after;  
                    fill(position, old_finish, x_copy);  
                }  
            }  
            else  
            {   // 剩下的备用空间小于“新增元素个数”(那就必须配置额外的内存)  
                // 首先决定新长度:就长度的两倍 , 或旧长度+新增元素个数  
                const size_type old_size = size();  
                const size_type len = old_size + max(old_size, n);  
                // 以下配置新的vector空间  
                iterator new_start = data_allocator::allocate(len);  
                iterator new_finish = new_start;  
                __STL_TRY  
                {  
                    // 以下首先将旧的vector的插入点之前的元素复制到新空间  
                    new_finish = uninitialized_copy(start, position, new_start);  
                    // 以下再将新增元素(初值皆为n)填入新空间  
                    new_finish = uninitialized_fill_n(new_finish, n, x);  
                    // 以下再将旧vector的插入点之后的元素复制到新空间  
                    new_finish = uninitialized_copy(position, finish, new_finish);  
                }  
#         ifdef  __STL_USE_EXCEPTIONS  
                catch(...)  
                {  
                    destroy(new_start, new_finish);  
                    data_allocator::deallocate(new_start, len);  
                    throw;  
                }  
#         endif /* __STL_USE_EXCEPTIONS */  
                destroy(start, finish);  
                deallocate();  
                start = new_start;  
                finish = new_finish;  
                end_of_storage = new_start + len;  
            }  
        }  
    }  
};  

最后总结一下:vector的用法:

begin(),end(),size(),capacity(),empty(),operator[]

front(), back(), push_back(), pop_back(), erase(position)

vector(2,9) //存2个9

原文地址:https://www.cnblogs.com/daocaorenblog/p/5299891.html