(2)、向新開辟的空間拷貝數(shù)據(jù)時,為什么不能用memcpy? 先來看一段代碼:
void _CheckCapacity() { if (_size == _capacity) { _capacity = _capacity * 2 + 3; T* tmp = new T[_capacity]; if (_a) { memcpy(tmp, _a, sizeof(T)*_size); /* for (size_t i = 0; i < _size; ++i) { tmp[i] = _a[i]; }*/ delete[] _a; } _a =tmp; } } 與之前的函數(shù)相比,這個_CheckCapacity()函數(shù)中用的是memcpy進行拷貝,而非for循環(huán),做了這樣的變化之后,我們給出兩個測試用例,看看會出現(xiàn)什么樣的結(jié)果? 同樣給出測試函數(shù)1: void TestStack1(){ Stack<int> s1; s1.Push(1); s1.Push(2); s1.Push(3); s1.Push(4); while (!s1.empty()) { cout << s1.Top() << endl; s1.Pop(); }}該函數(shù)的輸出結(jié)果如下:
由上圖可知,輸出正常,而當我們將數(shù)據(jù)類型換成string,會出現(xiàn)什么樣的情況呢?
對于以上的異常輸出,有兩點疑問:一是為什么程序會崩潰?二是為什么唯獨第二個字符串輸出的是隨機值? 先來看第一個問題:
由上圖可知,當舊空間中的string對象調(diào)用析構(gòu)函數(shù),將所指向的空間釋放了之后,新開辟空間中的string對象的指針就會指向一段未知的空間,變成野指針,因此程序會崩潰。 再來看第二個問題: 對比一下我們可以發(fā)現(xiàn),只有第二個字符串超過了16個字節(jié),而其他的字符串均沒有超過16個字節(jié),那為什么超過16個字節(jié)就會出現(xiàn)隨機值呢?因為string比較常用,因此系統(tǒng)對它進行了優(yōu)化,即string對象中除了指針以外,還有16個字節(jié)的buff,所以一旦string對象所指向的內(nèi)存空間中存儲的數(shù)據(jù)超過16個字節(jié),就會產(chǎn)生隨機值。 二、簡述隊列 1、概念 隊列也是一種線性表結(jié)構(gòu),
|
新聞熱點
疑難解答