1. 程式人生 > >關於vector大小(size)和容量(capacity)總結

關於vector大小(size)和容量(capacity)總結

操作大小的函式

        在Vector容器中有以下幾個關於大小的函式
方法 效果
size() 返回容器的大小
empty() 判斷容器是否為空
max_size() 返回容器最大的可以儲存的元素
capacity() 返回容器當前能夠容納的元素數量

例子一:

      該例子主要展示了關於大小操作函式的使用與區別
int _tmain(int argc, _TCHAR* argv[])
{
	vector<string> sentence;
	sentence.reserve(5);
	
	//append some elements
	sentence.push_back("hello");
	sentence.push_back("how");
	sentence.push_back("are");
	sentence.push_back("you");
	sentence.push_back("?");
	copy(sentence.begin(), sentence.end(), ostream_iterator<string>(cout, " "));
	cout << endl;

	//print "technical data"
	cout << "max_size():" << sentence.max_size() << endl;
	cout << "size():" << sentence.size() << endl;
	cout << "capacity():" << sentence.capacity() << endl;
	
	cout << "**************************" << endl;
	
	//swap second and fourth element
	swap(sentence[1], sentence[3]);	
	//insert element "always" before element "?"
	sentence.insert(find(sentence.begin(), sentence.end(), "?"), "always");
	//assign "!" to the last element
	sentence.back() = "!";
	copy(sentence.begin(), sentence.end(), ostream_iterator<string>(cout, " "));
	cout << endl;

	//print "technical data"
	// return maximum possible length of sequence 
	//回容器的最大可以儲存的元素個數,這是個極限,當容器擴充套件到這個最大值時就不能再自動增大
	cout << "max_size():" << sentence.max_size() << endl;
	// return length of sequence
	cout << "size():" << sentence.size() << endl;
	// return current length of allocated storage
	cout << "capacity():" << sentence.capacity() << endl;
	return 0;
}
        Vector的容量之所以重要,有以下兩個原因:          1. 容器的大小一旦超過capacity的大小,vector會重新配置內部的儲存器,導致和vector元素相關的所有reference、pointers、iterator都會失效。          2.記憶體的重新配置會很耗時間。 例子二: 該例子主要介紹了容器的重新配置導致iterator失效問題。
int _tmain(int argc, _TCHAR* argv[])
{
	vector<string> strVector;
	strVector.reserve(5);//當前空間夠大,不會發生重新配置,插入新元素後有可能會重新分配

	strVector.push_back("hello");
	strVector.push_back("C++");
	strVector.push_back("world");

	vector<string>::iterator it = strVector.begin();
	cout << "chang size befor, the first elemt:" << *it << endl;

	cout << "push_back one elems:." << endl;
	strVector.push_back("MS");
	cout << "push_back one elemt after, the first elemt:" << *it << endl;

	cout << "push_back two elems:" << endl;
	strVector.push_back("HW");
    strVector.push_back("BAT");//當前大小超過當前的容量,導致重新分配記憶體
	//it = strVector.begin(); 記憶體重新分配後,重新獲取指標可以避免指標失效
	cout << "push_back two elemts after, the first elemt:"<< *it << endl;//指標失效導致程式奔潰,

	return 0;
}

避免記憶體重新配置的方法

方法一:Reserve()保留適當容量

       在建立容器後,第一時間為容器分配足夠大的空間,避免重新分配記憶體。
std::vector<int> v;//create an empty vector
v.reverse(80);// reserve memory for 80 elements

方法二:利用建構函式創建出足夠空間

      該方法是建立容器時,利用建構函式初始化的出足夠的空間,
std::vector<int> v(80);

Vector記憶體擴充套件方式

          vector記憶體成長方式可歸結以下三步曲: (1)另覓更大空間;
(2)將原資料複製過去;
(3)釋放原空間三部曲。
如果不是vector每次配置新空間時都有留下一些餘裕,其成長假象所帶來的代價將是相當高昂,從記憶體的擴充套件方式就可以看出向vector插入元素,可能導致迭代器失效的原理。