2012-10-11 87 views
15

我在理解C++ clear函數的行爲時,遇到了一些困難,當應用於向量時。vector :: clear in C++

我試圖編譯並運行以下功能:

#include <iostream> 
#include <vector> 
using namespace std; 

int main() 
{ 
    unsigned int i; 
    vector<int> myvector; 
    myvector.push_back (1); 
    myvector.push_back (2); 
    myvector.push_back (3); 

    cout << "myvector contains:"; 
    for (i=0; i<myvector.size(); i++) cout << " " << myvector[i]; 

    myvector.clear(); 
    myvector.push_back (11); 
    myvector.push_back (12); 

    cout << "\nmyvector contains:"; 
    for (i=0; i<myvector.size(); i++) cout << " " << myvector[i]; 
    cout << endl; 

    cout << " entry3 = " << myvector[2]<<endl; 

    return 0; 
} 

這是輸出:

myvector contains: 1 2 3 
myvector contains: 11 12 
entry3 = 3 

這怎麼可能是向量的第三項的信息,也沒有清除矢量時已被刪除?

+2

operator []不是長度驗證索引。用.at(n)嘗試相同的操作,看看會發生什麼。 – WhozCraig

回答

22

從文檔:

所有向量的元素將被丟棄:他們的析構函數被調用,然後將它們從載體容器移除,留下容器的大小爲0。

基本上你正在調用未定義的行爲myvector[2]因爲該項目不再存在。在調用clear()之後,您僅向矢量推送了2個元素,因此只有索引01可以訪問。

你很倒黴,它沒有崩潰,因爲看起來工作可以隱藏錯誤。不能保證價值被抹去。

嘗試使用.at(2)訪問元素將導致引發異常(operator[]()不執行任何綁定檢查,而at()會)。

7

如果您嘗試在debug模式下運行此代碼,它很可能會因調試斷言而崩潰。引用過去數組的末尾是未定義的行爲

實際發生的情況是,在您運行clear()之前,矢量並未消除之前使用的內存。這個內存仍然存在,但沒有定義如果你訪問它會發生什麼。這取決於你執行邊界檢查以避免運行矢量的末端。您可以通過以size()作爲邊界循環或使用at()並捕獲out_of_range例外來完成此操作。我不會特別推薦這種後一種方法,因爲使用異常進行運行時檢查並不是一個好主意。