0.uninitialized_copy

template<class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);

如果[result, result+(ast-first))范围内的每一个迭代器都指向未初始化区域,则uninitialize_copy()

会使用copsy_constructor,给[first, last)范围内的每一个对象进行拷贝

0.uninitialized_fill

template <class ForwardIterator, class T>
void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);

0.uninitialized_fill_n

template<class ForwardIterator, class Size, Class T>
ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x);

0.destroy函数

template<class T>
inline void destroy(T* pointer)
{pointer->~T();
}template <class ForwardIterator>
inline void destroy(ForwardIterator first, ForwardIterator last)
{_-destroy(first, last, value_type(first));
}template void __destroy(ForwardIterator first, ForwardIterator last, T*)
{typedef typename __type_traits<T>::has_trival_destructor trival_destructor;__destroy_aux(first, last, trival_destructor());
}template<class ForwardIterator>
inline void __destroy_aux(ForwardIterator first, ForwardIterator last, __false_type)
{for (; first < last, ++first){destroy(&*first);}
}

1.vector中的迭代器

vector中的迭代器就是普通指针

template<class T, class Alloc=alloc>
class vector
{
public:typedef T value_type;typedef value_type* pointer;typedef value_type* iterator;typedef value_type& redference;typedef size_t size_type;typedef ptrdiff_t difference_type;
protected:typedef simple_alloc<value_type, Alloc> data_allocator;iterator start;iterator finish;iterator end_of_storage;
}

1.erase函数

执行完erase之后,当前iterator的状态是不确定的

vector<T>:: iterator erase(vector<T>::iterator pos);
vector<T>:: iterator erase(vector<T>::iterator begin, vector<T>::iterator end);

但是erase返回删除后指向的下一个位置

假如数组长这样:1 2 3 3 4

for (vector<int>::iterator iter = vec.begin(); iter != vec.end(); iter++)
{if (*iter == 3) iter = vec.erase(iter);
}

这段代码结束后有几个3??

答案:1个。连续的第二个3不能被删除

还有个问题就是 如果是1 2 3,这种在vec.end()是无法执行++的

正确的代码

    vector<int> a = {1,2,3,3,4,5,6};for (vector<int>::iterator iter=a.begin(); iter!=a.end();){if (*iter == 3) iter = a.erase(iter);else ++iter;}

erase的原型:(摘自STL源码剖析)

iterator erase(iterator position)
{if (position + 1 != end())copy(postion+1, finish, position); // 后续元素向前移动--finish;destroy(finish); // 调用finishi指向对象的析构函数return position; // 把后一个位置的指针返回
}

2.vector的扩容

#include <iostream>
#include <vector>
using namespace std; using namespace std;
int main()
{vector<int> vec;cout << "initial capacity: " << vec.capacity() << endl;for (int i = 0; i < 10; i++){vec.push_back(i);cout << "vec is ";for (int num : vec){cout << num << " ";}cout << endl;cout << "capacity: " << vec.capacity() << endl;}return 0;
}

结果:

initial capacity: 0
vec is 0
capacity: 1
vec is 0 1
capacity: 2
vec is 0 1 2
capacity: 3
vec is 0 1 2 3
capacity: 4
vec is 0 1 2 3 4
capacity: 6
vec is 0 1 2 3 4 5
capacity: 6
vec is 0 1 2 3 4 5 6
capacity: 9
vec is 0 1 2 3 4 5 6 7
capacity: 9
vec is 0 1 2 3 4 5 6 7 8
capacity: 9
vec is 0 1 2 3 4 5 6 7 8 9
capacity: 13

可以看到每次push_back的时候,如果容量不够,会申请一块2*i+1的内存,并将原来的数据拷贝过去

看一看push_back的源代码

void push_back(cosnt T& x)
{if (finish != end_of_storage){construct(finish, x);++finish;}else{insert_aux(end(), x);}
}

下面是insert_aux(end(), x);

// 下面的是通用的插入函数
template<class T, class Alloc>
void vector<T, alloc>:: insert_aux(iterator position, const T& x)
{if (finish != end_of_storage){construct(fisnish, *(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;iterator new_start = data_allocator::allocate(len);iterator new_finish = newstart;try:{new_finish = uninitialized_copy(start, position, new_start);construct(new_finish, x);++new_finish;// 将备用空间中的内容也拷贝过来new_finish = uninitialized_copy(position, finish, new_finish);}catch(...) {destroy(new_start, new_finish);data_allocator::deallocate(new_start, len);throw;}destroy(begin(), end());deallocate();start = new_start;finish = new_finish;end_of_storage = new_start + len;}
}

动态增加大小,并不是在原空间空面续接新空间,而是

以原空间大小的两倍另外配置一块新空间,并将原空间的内容拷贝到新空间后,插入

之后释放原空间。

3.erase和pop_back的会改变已分配内存大小吗?

不会

pop_back();

void pop_back()
{--finish;destroy(finish);
}

清除[first, last)

iterator erase(iterator first, iterator last)
{iterator i = copy(last, finish, first);destroy(i, finish);finish = finish - (last - first);return first;
}

下面是清除所有元素

void clear()
{erase(begin(), end());
}

4.size_t capacity()怎么算的?

size_type capacity() const
{return size_type(end_of_storage - begin());
}

5.vector的初始化

vector(size_type n, const T& value)
{fill_initialize(n, value);
}void fill_initialize(size_type n, constT & value)
{start = allocate_and_fill(n, value);finish = start + 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); // constructreturn result;
}

6. insert函数

template <class T, class Alloc>
void vector<T, Alloc>::insert(iterator position, size_type n, const T&x)
{if (n != 0){if (size_type(end_of_storage - finish) >= n) // 空间够用{T x_copy = x;cosnt size_type elems_after = finish - position;Iterator old_finish = finish;if (elems_after > n){uninitialized_copy(finish-n, finish, finish);finish += n;copy_backward(position, old_finish-n, old_finish);fill(position, postion+N, x_copy);}else{uninitialized_fill_n(finish, n-elems_after, x_copy);finish += n-elems_after;uninitialized_copy(postion, old_finish-n, 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);iterator new_start = data_allocator::allocate(len);iterator new_finish = new_start;__STL_TRY {new_finish = uninitialized_copy(start, position, new_start);new_finish = uninitialized_fill_n(new_finish, n, x);new_finish = uninitialize_copy(position, finish, new_finish);}# ifdef __STL_USE_EXCEPTIONScatch() {destroy(new_start, new_finish);data_allocator::deallocate(new_start, len);throw;}destroy(start, finish);deallocate();start = new_start;finish = new_finish;end_of_storage = new_start + len;}
}

c++ vector 中的坑相关推荐

  1. C++:vector中使用.clear()函数

    vector.clear()函数并不会把所有元素清零. vector有两个参数,一个是size,表示当前vector容器内存储的元素个数,一个是capacity,表示当前vector在内存中申请的这片 ...

  2. (四)Asp.net web api中的坑-【api的返回值】

    (四)Asp.net web api中的坑-[api的返回值] 原文:(四)Asp.net web api中的坑-[api的返回值] void无返回值 IHttpActionResult HttpRe ...

  3. JDK中的坑:JDK中这些方法的bug你不要踩

    点击关注公众号,Java干货及时送达 图片来源:白夜追凶 前言: jdk作为我们每天必备的调用类库,里面大量提供了基础类供我们使用.可以说离开jdk,我们的java代码寸步难行,jdk带给我们的便利可 ...

  4. C# System.Timers.Timer中的坑,程序异常退出后timer依然运行问题

    C# System.Timers.Timer中的坑,程序异常退出后timer依然运行问题 参考文章: (1)C# System.Timers.Timer中的坑,程序异常退出后timer依然运行问题 ( ...

  5. vector中find 的用法

    vector没有自带的find函数,需要用普通的find函数,使用如下: vector<string> nameList1; //给nameList1赋值 string name; if( ...

  6. 决策树python建模中的坑 :ValueError: Expected 2D array, got 1D array instead:

    决策树python建模中的坑 代码 #coding=utf-8 from sklearn.feature_extraction import DictVectorizerimport csvfrom ...

  7. C++ vector中的resize,reserve,size和capacity函数讲解

    前言 在介绍resize(),reserve(),size()和capacity()函数之前,先简单介绍一下c++中vector的概念. vector:顺序容器(可变大小数组).支持快速随机访问.在尾 ...

  8. 小心 Enum Parse 中的坑

    小心 Enum Parse 中的坑 Intro 最近使用枚举的时候,踩了一个小坑,分享一下,主要是枚举从 int 值转成枚举时可能会遇到 Sample 来看下面的示例: 首先定义一个枚举: publi ...

  9. C++从vector中删除指定元素

    ①只删除一个元素 vector<int> num;for(vector<int>::iterator iter=num.begin();iter!=num.end();iter ...

最新文章

  1. XCODE 6.1.1 配置GLFW
  2. 怎么快速解决KeyShot占CPU100%问题
  3. Win10如何打开软键盘?
  4. java 模板引擎_SpringBoot入门系列(四)如何整合Thymeleaf模板引擎
  5. BZOJ1856:[SCOI2010]字符串
  6. 基于 IdentityServer3 实现 OAuth 2.0 授权服务【密码模式(Resource Owner Password Credentials)】...
  7. 【HTTPS运维神器】终于等到你!MySSL企业版重磅上线!
  8. contact form 7如何设置placeholder让提示文字显示在输入框中
  9. Axure8.0 注册码
  10. 太阳高度角计算题_【难点突破】太阳高度角与正午太阳高度角区别(附例题解析)...
  11. SPSS学习资料汇总
  12. asp.net pdf如何转换成tif_PDF如何转换成PPT文档?怎么使用PDF转换成PPT的软件?
  13. UE4实现风格化渲染(一):UserNormalTranslator工具的使用
  14. LiveCharts
  15. 哈利波特魔法觉醒游戏攻略分析
  16. D3D9学习笔记之精灵变换篇
  17. KVM虚拟化技术的-NUMA技术和应用
  18. python开发微信订阅号如何申请_基于Python的微信公众平台二次开发(Python常用框架、订阅号开发、公众号开发)...
  19. clickhouse 副本引擎
  20. 日本金融监管机构将推出新的ICO法规

热门文章

  1. 激光雷达选型指南 这2项重要指标却被很多人忽略
  2. HTML5 Canvas 绘制佛教万字
  3. solr学习二(ExtractingRequestHandler)
  4. 消灭Bug!推荐7款优秀的开源Bug跟踪工具
  5. Codeforces Round #232 Editorial Div2-B
  6. Vert.x学习笔记(一) Vert.x 核心包
  7. 23种设计模式之外观模式(Facade)
  8. __getattribute__()、__getattr__()、__setattr__()、__delattr__()
  9. 最值得一看的几条简单的谷歌 Google 搜索技巧!
  10. 商品的包装(外贸知识二)