2012-01-25 74 views
5

如何訪問元素從myVector像我將與陣列(for(i = 0; i < n; i++) cout << v[i] << " ";C++向量訪問元素

我的代碼:

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

class Month 
{ 
public: 
    char *name; 
    int nr_days; 
    Month(char* c, int nr) : name(c), nr_days(nr){}; 
    ~Month() { /* free(name); */} 
}; 

int main() 
{ 
    Month January("January", 31); 
    Month February("February", 28); 
    Month March("March", 31); 
    Month April("April", 30); 
    Month May("May", 31); 
    Month June("June", 30); 
    Month July("July", 31); 
    Month August("August", 31); 
    Month September("September", 30); 
    Month Octomber("Octomber", 31); 
    Month November("November", 30); 
    Month December("December", 31); 

    vector<Month> *myVect = new vector<Month>; 
    myVect->push_back(January); 
    myVect->push_back(February); 
    myVect->push_back(March); 
    myVect->push_back(April); 
    myVect->push_back(May); 
    myVect->push_back(June); 
    myVect->push_back(July); 
    myVect->push_back(August); 
    myVect->push_back(September); 
    myVect->push_back(Octomber); 
    myVect->push_back(November); 
    myVect->push_back(December); 

    for(vector<Month>::const_iterator i = myVect->begin(); i != myVect->end(); i++) 
    { 
     /* 
     Month myMonth = i; 
     cout << myMonth.name << " " << myMonth.nr_days << endl; 
     */ 
    } 

    free(myVect); 
    return 0; 
} 

我想成爲像一個foreach算法:foreach(Month in myVect) cout << ...

另一個問題:如果我取消註釋我的行,它爲什麼會在析構函數中給我一個運行時錯誤?

+0

首先,你可能不想讓'myVect'成爲一個*指針*,但是如果你這樣做了,你需要用new來分配。我很驚訝它不會早點崩潰。 – crashmstr

+0

我在想,「新......」在Adam編輯中被刪除了......? – crashmstr

+0

@crashmstr:就是這樣。爲了羞恥亞當,爲了羞恥...... –

回答

7

好吧,這裏有很多問題。

  1. 您聲明myVect作爲指向矢量的指針。這是不必要的。使用矢量的一個主要好處是,您不必擔心內存管理,因爲vector可以爲您做。你堆棧分配的矢量,但內部它堆分配用於存儲它包含的項目的內存。

  2. 您從不初始化指針。您正在調用未定義的行爲,因爲該指針無效。初始化您使用的指針new。你所擁有的是一個無效堆棧分配指針,它不指向堆上的vector。編輯:我剛剛意識到new被編輯出來,所以你可以忽略這一個。不過,它不應該是一個指針。

  3. 您正在使用free來釋放C++類(您從來沒有分配過以......開頭)。別。這不是C,您使用newdelete來管理C++中的內存(必要時!)。 free不調用析構函數,它只是釋放一大塊內存。另一方面,delete確實知道如何處理複雜的C++類型。 從不混合new/deletemalloc/free

  4. myVect->begin()返回const_iterator而不是T(即,在這種情況下,不是Month對象)。通過*運營商提領該迭代將產生當前迭代的對象,所以:


Month myMonth = *i // <--- IMPORTANT! 

順便說一句,如果你將要遍歷向量時候,你可能希望到typedef迭代器,以減少冗長,即

typedef vector<Month>::const_iterator cmonth_iter; 

現在你可以寫

for(cmonth_iter i = myVect.Begin(); i != myVect.end(); ++i) 
{ 
    Month m = *i; 
    // do stuff with m  
} 
2

您可以訪問使用迭代器使用*操作元素:

for(vector<Month>::const_iterator i = myVect->begin(); i != myVect->end(); i++) 
{ 
    Month myMonth = *i; 
    cout << myMonth.name << " " << myMonth.nr_days << endl; 
} 

而且,你永遠不分配代碼中的vector。對於您之前未從malloc()收到的指針,您不應使用free()。這是未定義的行爲,否則可能會在您撥打free()時發生運行時錯誤。

試試這個:

vector<Month> *myVect = new vector<Month>; 
... 
delete myVect; 
1

如果通過更改刪除未初始化指針錯誤:

vector<Month> *myVect; 

到:

vector<Month> myVect; 

,那麼這將正常工作。 (一旦你定義ostream << Month

for(i = 0; i < myVect.size(); i++) 
cout << v[i] << " "; 
0
  1. 你有一個指針myVect,但從來沒有使用(上轉編譯器警告)之前將值分配給它。你應該做一些像myVect = new vector<Month>()。 (或者不要使它成爲指針並將->更改爲.)。其餘的「foreach」實現看起來很好。你也可以使用[]來訪問元素。

  2. 你可以釋放常量字符串,但你沒有分配它們,所以你也不需要釋放它們。

0

你聲明myVect作爲指針,但從不分配它,這會給你很多麻煩。只需放下*,你應該沒問題。

如果你堅持,你可以使用索引,就像你會與一個數組:

for(int i = 0; i < myVect.size(); i++) 
{   
    Month myMonth = myVect[i]; 
    cout << myMonth.name << " " << myMonth.nr_days << endl; 
} 

雖然我寧願使用迭代器爲你做了 - 只是一個簡單的解決方法:

Month myMonth = *i; 
0

您可以使用迭代器箭頭操作符...

for(vector<Month>::const_iterator i = myVect->begin(); i != myVect->end(); i++) 
{ 
    cout << i->name << " " << i->nr_days << endl; 
} 

還要注意它與更地道迭代器使用++i而不是i++(原因是i++需要創建將被丟棄的迭代器的副本)。

還請注意,您的代碼是UB(未定義的行爲),因爲您正在使用指向矢量的指針,但未分配它。順便說在這種情況下,使用指針的是廢話,用代碼將是正確的,更簡單的:

vector<Month> myVect; 
myVect.push_back(January); 
myVect.push_back(February); 
... 
for(vector<Month>::const_iterator i = myVect.begin(); i != myVect->end(); ++i) 
    ... 

我的建議也避免嘗試只用一個編譯器嘗試學習C++(東西,我有你想要做的印象)。

C++是強大的,但也很複雜,不幸的是很多地方很不合邏輯和不對稱(由於它的演變歷史)。除此之外,當你犯了一個錯誤(例如不在你原來的代碼中分配向量)時,你不能期望編譯器能夠幫助你,甚至在運行時程序也可以做任何事情,包括顯然按你期望的那樣工作(最糟糕的事情) 。這個組合是致命的。

複雜性,不對稱性和缺少運行時檢查都使C++無法通過實驗學習......只需獲得good book並閱讀它。這種方式更簡單。