C++:新概念!获取你想知道的!!

标题说明

标题党了.这次遇到的是capacity,可以获取vector和string不重新分配内存空间的话,当前容器可以保存多少元素.

不重新分配内存空间,当前容器可以保存多少元素,这个概念很重要。看图:

c++ capacity
image-2059

题目

解释下面的程序片段做了什么:

1
2
3
4
5
6
7
8
9
10
11
vector<string> svec;
svec.reserve(1024);//1
string word;
while(cin >> word)//2
{
    svec.push_back(word);
}
svec.resize(svec.size()+svec.size()/2);//3
//下面这句是新添加的,可以猜一下输出结果.
cout << "svec.size():" << svec.size() << endl;//4
cout << "svec.size():" << svec.capacity() << endl;//5

源码及解答

解答:

  • 在[1]这个地方为vector分配最少1024个空间
  • 在[2]添加元素,假如添加的元素个数是n[看下面,添加数量不一定.]个
  • 在[3]这个地方对容器的大小进行调整

可以猜一下在上面[4]和[5]要输出的值.【capacity的值完全依赖于实现,因此可能有所差异.及以下运行结果来自:gcc 4.8.2版本.】

源码1

添加数量为256个元素.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*************************************************************************
    > File Name: test.9.39.cpp
    > Author: puruidong
    > Mail: 1@w1520.com
    > Created Time: 2014年05月22日 星期四
 ************************************************************************/

#include<iostream>
#include<vector>
using namespace std;

int main()
{
    /*
   
    解释下面的程序片段做了什么?
    1.要求系统分配一个1024大小的空间;
    2.向vector中添加256个元素;
    3.缩小元素空间,vector中的实际元素是256个,由于除法是优先运算的,
    因此3的运算结果大致是256+256/2=384


    */
    vector<string> svec;
    svec.reserve(1024);//1
    //while(cin >> word)
    for(unsigned i=0;i!=256;++i)//2
    {
        svec.push_back(i+"test");
    }
    svec.resize(svec.size()+svec.size()/2);//3
    cout << "test>>" << svec.size() << endl;
    cout << "capacity>>" << svec.capacity() << endl;//此行输出依赖具体实现,我测试输出为1024.
    return 0;
}

c++ running
image-2060

源码2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*************************************************************************
    > File Name: test.9.39.cpp
    > Author: puruidong
    > Mail: 1@w1520.com
    > Created Time: 2014年05月22日 星期四
 ************************************************************************/

#include<iostream>
#include<vector>
using namespace std;

int main()
{
    /*
   
    解释下面的程序片段做了什么?
    1.要求系统分配一个1024大小的空间;
    2.向vector中添加512个元素;
    3.缩小元素空间,vector中的实际元素是512个,由于除法是优先运算的,
    因此3的运算结果大致是512+512/2=768.
    capacity的输出是1024[未超过预先设置的空间容量].

    */
    vector<string> svec;
    svec.reserve(1024);//1
    //while(cin >> word)
    for(unsigned i=0;i!=512;++i)//2
    {
        svec.push_back(i+"test");
    }
    svec.resize(svec.size()+svec.size()/2);//3(512+512/2)
    cout << "test>>" << svec.size() << endl;
    cout << "capacity>>" << svec.capacity() << endl;//输出结果依赖具体实现,此处输出1024.
    return 0;
}

C++.
image-2061

源码3

源码1和2有一个共同的特点,[3]的结算结果均未超过1024.下面的会有变化.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*************************************************************************
    > File Name: test.9.39.cpp
    > Author: puruidong
    > Mail: 1@w1520.com
    > Created Time: 2014年05月22日 星期四
 ************************************************************************/

#include<iostream>
#include<vector>
using namespace std;

int main()
{
    /*
   
    解释下面的程序片段做了什么?
    1.要求系统分配一个1024大小的空间;
    2.向vector中添加1000个元素;
    3.缩小元素空间,vector中的实际元素是1000个,由于除法是优先运算的,
    因此3的运算结果大致是(1000+500)=1500.
    4.容器长度未超出1024时,为1024.{超过则会新分配空间,具体依赖实现.}

    */
    vector<string> svec;
    svec.reserve(1024);//1
    //while(cin >> word)
    for(unsigned i=0;i!=1000;++i)//2
    {
        svec.push_back(i+"test");
    }
    svec.resize(svec.size()+svec.size()/2);//3
    cout << "test>>" << svec.size() << endl;
    cout << "capacity>>" << svec.capacity() << endl;//4,此处输出2000,新分配的空间为原空间的三分之一[新分配空间依赖具体实现].
    return 0;
}

源码4

一直在重申[capacity]的值依赖具体实现,因此可能不同平台,输出结果不同.每个vector的实现策略不同(比如gcc,ms vc),但是必须遵守一个原则:只有当迫不得已时才会分配新内存空间.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*************************************************************************
    > File Name: test.9.39.cpp
    > Author: puruidong
    > Mail: 1@w1520.com
    > Created Time: 2014年05月22日 星期四
 ************************************************************************/

#include<iostream>
#include<vector>
using namespace std;

int main()
{
    /*
   
    解释下面的程序片段做了什么?
    1.要求系统分配一个1024大小的空间;
    2.向vector中添加1048个元素;
    3.缩小元素空间,vector中的实际元素是1048个,由于除法是优先运算的,
    因此3的运算结果大致是1048+1048/2=1572.
    *****************************************************************
    此处vector实际元素已经超出了预先分配的空间,因此必须新分配内存空间,新分配的空间长度不少于元素的个数.
    而capacity的值也会发生变化,{这依赖具体实现}.capacity在此处输出:2048[在实际元素数量上增加了1000个内存空间].

    */
    vector<string> svec;
    svec.reserve(1024);//1
    //while(cin >> word)
    for(unsigned i=0;i!=1048;++i)//2
    {
        svec.push_back(i+"test");
    }
    svec.resize(svec.size()+svec.size()/2);//3
    cout << "test>>" << svec.size() << endl;
    cout << "capacity>>" << svec.capacity() << endl;//4
    return 0;
}

关于capacity还有很多问题值得思考,上面的程序在gcc 4.8.2上测试通过[使用C++11进行编译].