内存管理与效率
size()
获得容器中有多少元素
capacity()
获得容器在它已经分配的内存中可以容纳多少元素
resize(Container::size_type n)
强制将容器改为容纳n个元素。调用resize函数之后,size函数将返回n。
当n小于当前大小,尾部元素被销毁
当n大于当前大小,新默认构造的元素会添加到容器尾部
当n大于当前容量,在元素加入之前会进行重新分配
reserve(Container::size_type n)
强制容器把它的容量改为不小于n,提供的n不小于当前所需的大小。因为容量需要增加,这个会强迫进行一次重新分配。如果当n小于当前容量,vector会忽略它。
这段代码会导致2~10次重新分配(每次容量翻倍,涉及到拷贝)
vector<int> v;
for(int i = 1;i < = 1000;++i)
v.push_back(i);
使用reserve
vector<int> v;
v.reserve(1000);
for(int i = 1;i < = 1000;++i)
v.push_back(i);
使用“交换技巧”来修整vector过剩空间/内存
vector<int>(ivec).swap(ivec)
vector<int>(ivec)
表示建立一个临时的vector,是ivec的一份拷贝。但是,vector的拷贝构造函数只分配拷贝的元素需要的内存,所以这个临时的vector没有多余的容量。然后临时的vector和ivec交换数据完成。ivec只有临时变量的修正过的容量,而临时vector由原来ivec未使用的容量,在语句结尾处,临时vector被销毁,释放,收缩到合适的大小。
vector内存管理成员函数的行为测试
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> iVec;
cout<<"容器大小:"<<iVec.size()<<"容量:"<<iVec.capacity()<<endl;
/*1个元素,容器容量为1*/
iVec.push_back(1);
cout<<"容器大小:"<<iVec.size()<<"容量:"<<iVec.capacity()<<endl;
/*2个元素,容器容量为2*/
iVec.push_back(2);
cout<<"容器大小:"<<iVec.size()<<"容量:"<<iVec.capacity()<<endl;
/*3个元素,容器容量为4*/
iVec.push_back(3);
cout<<"容器大小:"<<iVec.size()<<"容量:"<<iVec.capacity()<<endl;
/*4个元素,容器容量为4*/
iVec.push_back(4);
cout<<"容器大小:"<<iVec.size()<<"容量:"<<iVec.capacity()<<endl;
/*5个元素,容器容量为8*/
iVec.push_back(5);
cout<<"容器大小:"<<iVec.size()<<"容量:"<<iVec.capacity()<<endl;
/*6个元素,容器容量为8*/
iVec.push_back(6);
cout<<"容器大小:"<<iVec.size()<<"容量:"<<iVec.capacity()<<endl;
/*7个元素,容器容量为8*/
iVec.push_back(7);
cout<<"容器大小:"<<iVec.size()<<"容量:"<<iVec.capacity()<<endl;
/*8个元素, 容器容量为8*/
iVec.push_back(8);
cout<<"容器大小:"<<iVec.size()<<"容量:"<<iVec.capacity()<<endl;
/*9个元素, 容器容量为16*/
iVec.push_back(9);
cout<<"容器大小:"<<iVec.size()<<"容量:"<<iVec.capacity()<<endl;
/* vs2005/8 容量增长不是翻倍的,如
9个元素 容量9
10个元素 容量13 */
/* 测试effective stl中的特殊的交换 swap() */
cout<<"容器大小:"<<iVec.size()<<"容量:"<<iVec.capacity()<<endl;
vector<int>(iVec).swap(iVec);
cout<<"临时的vector<int>对象的大小为:"<<(vector<int>(iVec)).size()<<endl;
cout<<"临时的vector<int>对象的容量为: " <<(vector<int>(iVec)).capacity()<<endl;
cout<<"交换后,当前vector的大小为:"<<iVec.size()<<endl;
cout<<"交换后,当前vector的容量为:"<< iVec.capacity()<<endl;
return 0;
}
Vector类的简单实现
#include<algorithm>
#include<iostream>
#include <assert.h>
using namespace std;
template<typename T>
class myVector
{
private:
/*walk length*/
/*myVector each time increase space length*/
#define WALK_LENGTH 64;
public:
/*default constructor*/
myVector():array(0),theSize(0),theCapacity(0){ }
myVector(const T& t,unsigned int n):array(0),theSize(0),theCapacity(0){
while(n--){
push_back(t);
}
}
/*copy constructor*/
myVector(const myVector<T>& other):array(0),theSize(0),theCapacity(0){
*this = other;
}
/*= operator*/
myVector<T>& operator =(myVector<T>& other){
if(this == &other)
return *this;
clear();
theSize = other.size();
theCapacity = other.capacity();
array = new T[theCapacity];
for(unsigned int i = 0 ;i<theSize;++i)
{
array[i] = other[i];
}
return *this;
}
/*destructor*/
~myVector(){
clear();
}
/*the pos must be less than myVector.size();*/
T& operator[](unsigned int pos){
assert(pos<theSize);
return array[pos];
}
/*element theSize*/
unsigned int size(){
return theSize;
}
/*alloc theSize*/
unsigned int capacity(){
return theCapacity;
}
/*is empty*/
bool empty(){
return theSize == 0;
}
/*clear myVector*/
void clear(){
deallocator(array);
array = 0;
theSize = 0;
theCapacity = 0;
}
/*adds an element in the back of myVector*/
void push_back(const T& t){
insert_after(theSize-1,t);
}
/*adds an element int the front of myVector*/
void push_front(const T& t){
insert_before(0,t);
}
/*inserts an element after the pos*/
/*the pos must be in [0,theSize);*/
void insert_after(int pos,const T& t){
insert_before(pos+1,t);
}
/*inserts an element before the pos*/
/*the pos must be less than the myVector.size()*/
void insert_before(int pos,const T& t){
if(theSize==theCapacity){
T* oldArray = array;
theCapacity += WALK_LENGTH;
array = allocator(theCapacity);
/*memcpy(array,oldArray,theSize*sizeof(T)):*/
for(unsigned int i = 0 ;i<theSize;++i){
array[i] = oldArray[i];
}
deallocator(oldArray);
}
for(int i = (int)theSize++;i>pos;--i){
array[i] = array[i-1];
}
array[pos] = t;
}
/*erases an element in the pos;*/
/*pos must be in [0,theSize);*/
void erase(unsigned int pos){
if(pos<theSize){
--theSize;
for(unsigned int i = pos;i<theSize;++i){
array[i] = array[i+1];
}
}
}
private:
T* allocator(unsigned int size){
return new T[size];
}
void deallocator(T* arr){
if(arr)
delete[] arr;
}
private:
T* array;
unsigned int theSize;
unsigned int theCapacity;
};
void printfVector(myVector<int>& vector1){
for(unsigned int i = 0 ; i < vector1.size();++i){
cout<<vector1[i]<<",";
}
cout<<"alloc size = "<<vector1.capacity()<<",size = "<<vector1.size()<<endl;
}
int main(){
myVector<int> myVector1;
myVector<int> myVector2(0,10);
myVector2.push_front(1);
myVector2.erase(11);
printfVector(myVector2);
myVector1.push_back(2);
myVector1.push_front(1);
printfVector(myVector1);
myVector1.insert_after(1,3);
printfVector(myVector1);
myVector2 = myVector1;
myVector2.insert_before(0,0);
myVector2.insert_before(1,-1);
printfVector(myVector2);
return 0;
}