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

标题说明

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

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

c++ capacity
image-2059

题目

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


vector 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个元素.


/*************************************************************************
> File Name: test.9.39.cpp
> Author: puruidong
> Mail: 1@w1520.com
> Created Time: 2014年05月22日 星期四
************************************************************************/

#include
#include
using namespace std;

int main()
{
/*

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

*/
vector 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


/*************************************************************************
> File Name: test.9.39.cpp
> Author: puruidong
> Mail: 1@w1520.com
> Created Time: 2014年05月22日 星期四
************************************************************************/

#include
#include
using namespace std;

int main()
{
/*

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

*/
vector 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.下面的会有变化.

/*************************************************************************
> File Name: test.9.39.cpp
> Author: puruidong
> Mail: 1@w1520.com
> Created Time: 2014年05月22日 星期四
************************************************************************/

#include
#include
using namespace std;

int main()
{
/*

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

*/
vector 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),但是必须遵守一个原则:只有当迫不得已时才会分配新内存空间.


/*************************************************************************
> File Name: test.9.39.cpp
> Author: puruidong
> Mail: 1@w1520.com
> Created Time: 2014年05月22日 星期四
************************************************************************/

#include
#include
using namespace std;

int main()
{
/*

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

*/
vector 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进行编译].

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据