Skip to main content
  1. Posts/

cpp vector学习笔记

·785 words·2 mins
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

起因是百度实习二面的时候被问了一道类似这样的题:

给我下面的代码,问有没有什么问题。

 1/* ***********************************************
 2Author :111qqz
 3Created Time :2017年02月28日 星期二 14时49分37秒
 4File Name :vector.cpp
 5************************************************ */
 6#include <cstdio>
 7#include <vector>
 8#include <ctime>
 9using namespace std;
10int func( int x ) //此处函数的条件是不单调...这样才可以触发问题.
11{
12    return (x-50)*(x-50)+1;
13}
14int main()
15{
16
17    vector<int>vec;
18    int *pint = NULL;
19    for ( int i = 0 ; i < 100 ; i++)
20    {
21        int x = func(i);
22        vec.push_back(x);
23        if (x<500)
24        {
25            pint = & vec[0];
26        }
27    }
28    if (pint)
29        *pint = 0 ;
30    int siz = vec.size();
31    for ( int i = 0  ; i < siz ; i++) printf("%d\n",vec[i]);
32    return 0;
33}

面试的时候只给了部分代码,func函数没有给出。

当时没有看出问题在哪里…

后来知道了,这道题其实考的是vector的底层实现…

以下内容参考《STL源码解析》4.2章 侯捷著

std::vector 内部结构
vector 扩容前
vector 扩容与搬移

vector是动态增加空间,但是并不是在原空间后面增加新空间(因为不能保证原空间之后是否还有可以配置的空间),而是以原大小的两倍另外配置一块较大空间,然后将原内容拷贝过来,之后才开始在原内容后面构建新内容,并释放原空间。
#

因此,对vector的任何操作,一旦引起对空间重新配置,指向原vector的所有迭代器都失效了!

vector采取的存储方式是连续线性空间,用两个迭代器start和finish分别指向当前配置的空间中已经使用的部分的开始和结尾,用另一个迭代器end_of_storage指向当前配置的整块连续空间(包含备用部分)的尾端。

当我们用push_back()将元素插入vector尾端时,push_back()会先检查是否还有备用空间,如果有就直接在备用空间上构建元素,并调整迭代器finish,使vector变大。如果没有备用空间了,就扩充空间。

可以用以下代码来测试:

 1/* ***********************************************
 2Author :111qqz
 3Created Time :2017年02月28日 星期二 14时33分10秒
 4File Name :vector1.cpp
 5************************************************ */
 6#include <cstdio>
 7#include <vector>
 8#include <iostream>
 9using namespace std;
10int main()
11{
12    vector<int>a;
13    a.push_back(0);
14    int lst = -1;
15    for ( int i = 0 ; i < 200 ; i++)
16    {
17        a.push_back(-1);
18//	if (a.capacity()!=lst)
19        printf("i:%d %d ",i,a.capacity());
20        cout<<&a[0]<<endl;
21        lst = a.capacity();
22    }
23    return 0;
24}

结果如下:

vector 测试输出

Related

c++11 学习笔记

·172 words·1 min
昨天终于搞定了ycm对c++11的支持…. 嘛,17都快出来了,我竟然连11都不会用。

c语言中static的作用

·185 words·1 min
一般有两个 1static int a; 2int b; 3void func(void) 4{ 5 static int c=0; 6 int d; 7} 在这里,a与b都是全局变量,二者的区别是,b可以被别的文件使用,a只能在本文件中使用,这是static对全局变量的作用。 ** c和d的区别是,d是一个自动变量,func函数执行完后,d会自动被释放。但c却不会被释放,下一次调用func函数时,c的值会保留上次的值继续使用(而不是初始值0,初始化只会在函数第一次被调用的时候执行)**

0x3f3f3f3f...编程中无穷大常量的设置技巧

·1368 words·3 mins
如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取0x7fffffff作为无穷大,因为这是32-bit int的最大值。如果这个无穷大只用于一般的比较(比如求最小值时min变量的初值),那么0x7fffffff确实是一个完美的选择,但是在更多的情况下,0x7fffffff并不是一个好的选择。