[英]Class template vector with pop_back function does not work as I intended
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> VectorName;
VectorName.push_back(2);
VectorName.push_back(3);
cout << VectorName[1] << endl;
VectorName.pop_back();
cout << VectorName[1] << endl;
}
以我的理解,pop_back()假定彈出向量的最后一個索引,而我期望編譯的結果是給我一個錯誤。 但是,控制台上的輸出表示為:
3 3
有人會解釋為什么該程序的編譯成功嗎?
謝謝。
vector<>::operator[]()
不檢查向量的大小,因此您的代碼正在產生未定義的行為。
在您的特定情況下,調用pop_back()
時,矢量的大小 (矢量中的項目數)正在縮小,但容量 (基礎數組的大小)卻沒有pop_back()
。 這意味着第二個VectorName[1]
指向未使用但現有的內存。 例如,如果我們稍微編輯一下示例以檢查容量和大小,請執行以下操作:
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> VectorName;
VectorName.push_back(2); // |[2]|
VectorName.push_back(3); // |[2, 3]|
VectorName.pop_back(); // |[2], 3|
cout << VectorName.size() << endl;
cout << VectorName.capacity() << endl;
}
輸出為:
1
2
您可以在此處看到一個有效的示例: http : //coliru.stacked-crooked.com/a/70d5141bdc375b48
如您所見,向量的大小是正確的(1個項目),但是對VectorName.pop_back()
的調用不會減少容量,因此向量中仍然存在3
,但是無法訪問。
通過在調用VectorName.pop_back()
之后訪問第二項,您正在導致未定義的行為。 在您的情況下,您得到3
,但是使用其他編譯器,體系結構或機器編譯應用程序可能會導致您的應用程序崩潰(或更糟)!
使用vector<int>::at()
,而不是vector<int>::operator[]()
會引發std::out_of_range
異常,從而導致程序崩潰。 這是因為at()
函數檢查向量的大小並在嘗試訪問向量中的越界位置時引發異常。 也就是說,不要依賴at()
函數來檢查向量訪問, VectorName[1]
在調用VectorName[1]
之前先檢查向量的size()
。
例如,通過再次對代碼進行較小的編輯,我們可以看到使用at()
函數時會發生什么:
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> VectorName;
VectorName.push_back(2);
VectorName.push_back(3);
cout << VectorName.at(1) << endl;
VectorName.pop_back();
cout << VectorName.at(1) << endl;
return 0;
}
3
拋出'std :: out_of_range'實例后調用終止
what():vector :: _ M_range_check:__n(1)> = this-> size()(1)
bash:第7行:4793中止(核心已轉儲)./a.out
實時示例: http : //coliru.stacked-crooked.com/a/8226be85196f54fe
關於“編譯錯誤”的另一件事。 編譯器在訪問向量之前不會嘗試檢查其大小,因此,編譯器將愉快地編譯您的代碼而不會出現錯誤或警告。 作為開發人員,您需要對代碼執行邊界檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.