2014-03-25 66 views
1

我想通過它們的x座標讀取一個點列表到一個向量中。但是,我始終得到最後一個元素的向量。 例如,如果輸入的是push_back得到最後一個元素的向量

1 1 
2 2 
3 3 

輸出將是

3 3 
3 3 
3 3 

這裏是我的代碼:

#include <iostream> 
#include <vector> 
#include <algorithm> 

using namespace std; 

struct Point { 
    int x; 
    int y; 
}; 

typedef Point* ppt; 

int main() 
{ 
    //read input 
    int n; 
    cin >> n; 
    vector<ppt> v; 
    for(int i = 0; i < n; i ++){ 
     Point p; 
     ppt pp = &p; 
     cin >> pp->x; 
     cin >> pp->y; 
     v.push_back(pp); 
    } 
    for(int i = 0; i < n; i ++){ 
     ppt p = v.at(i); 
     cout << p->x << " " << p->y << endl; 
    } 
    return 0; 
} 

我閱讀文檔。如果我理解正確,vector :: push_back(pp)複製指針並將複製的值插入到v的末尾。那麼問題出在哪裏?

回答

3

你的代碼未定義的行爲,因爲在這裏

ppt p = v.at(i); 
cout << p->x << " " << p->y << endl; 

你試圖訪問一個已經被破壞對象:

{ 
    Point p; 
    ppt pp = &p; 
    cin >> pp->x; 
    cin >> pp->y; 
    v.push_back(pp); 

} // p is destructed here, so you have a dangling pointer in the vector 

Instea使用指針的載體Point的d使用std::vector<Point>,而是添加指針的對象:

std::vector<Point> v; 

//... 

Point p; 

cin >> p.x; 
cin >> p.y; 
v.push_back(p); 
+0

哪裏是被破壞的對象,爲什麼?你能解釋更多嗎? – Will

+1

看看更新後的答案,請 – soon

+0

@Will當您執行push_back向量時,它使用複製構造函數將元素複製到向量,所以將簡單指針複製(向淺拷貝)到向量中,因爲指針指向堆棧上的對象,當它退出scopoe/block「}」時,它會超出範圍。 – Singh

0

在你的第一個循環的每次迭代中,您要創建Point類型的變量和一個指向它,但在這個循環結束,該變量被破壞,你的指針變成懸空,

在下一次迭代,創建另一個變量並做

到底「在存儲相同的位置」同樣的事情,你的所有指針實際上指向一個被毀壞的對象,並呼籲dagling,但他們指到一個位置,並且此位置具有您最後保存的點的值。


此代碼應工作:

#include <iostream> 
#include <vector> 
#include <algorithm> 

using namespace std; 

struct Point { 
    int x; 
    int y; 
}; 

typedef Point ppt; 

int main() 
{ 
    //read input 
    int n; 
    cin >> n; 
    vector<ppt> v; 
    for(int i = 0; i < n; i ++){ 
     Point p; 
     cin >> p.x; 
     cin >> p.y; 
     v.push_back(p); 
    } 
    for(int i = 0; i < n; i ++){ 
     cout << v[i].x << " " << v[i].y << endl; 
    } 
    return 0; 
} 
+1

不,事實並非如此。如果輸出看起來符合那個解釋,那純粹是偶然的。行爲實際上是未定義的。 –

+1

你的解釋中的主要觀點 - 指針可能全部保持相同的地址 - 在實踐中很可能是真實的,但本傑明說不能保證。更重要的是,「null」並不意味着指向一個被摧毀的對象,這是你使用它的意義。空指針非常明確地說是'== 0',其中'vector'中的指針不會是。所以「你的指針變成一個空指針」是不正確的 - 它會變成「無效的」或[「dangling」](http://en.wikipedia.org/wiki/Dangling_pointer)。同上「所有的指針實際上都是空指針」。 –

3
for(int i = 0; i < n; i ++){ 
     Point p; 
     ppt pp = &p; 
     cin >> pp->x; 
     cin >> pp->y; 
     v.push_back(pp); 
    } 

這個代碼是錯誤,你構造對象Point p內的for循環,但是當你碾過for循環中,對象Point p被銷燬,但您將Point p的地址存儲到向量中,在銷燬對象Point p後,向量中的內容無效。

你可以這樣做:

for(int i = 0; i < n; i ++){ 
    ppt pp = new Point(); 
    cin >> pp->x; 
    cin >> pp->y; 
    v.push_back(pp); 
} 
相關問題