2016-03-03 96 views
-3

在向量中存儲指針對象時遇到困難。 我存儲這樣的值:淺拷貝與向量

face.firstEdge = &edge 
all_faces.push_back(face); 

其中face.edge是一個指向其它對象。 我的矢量聲明如下std::vector<Face> all_faces;和結構是:

struct Face{ 
    Edge* firstEdge 
} 

當我後來通過我的元素,看起來他們都具有相同的價值,他們shouln't有

for(int i = 0; i < all_faces.size(); i++){ 
    all_faces[i].firstEdge->vertex->x; 
} 

我知道C++編譯器默認做一個淺拷貝或者其他東西,所有東西指向同一個地址,我不想要這個。

編輯:邊緣是一個本地變量Edge edge = {};每次在循環中聲明和修改。

+3

向我們展示您的矢量聲明! – CinCout

+0

是否定義了face的複製構造函數?你可以顯示臉型的類型,矢量聲明等的定義。 – Ramon

+0

什麼範圍有「邊緣」? –

回答

1

我知道C++編譯器,使淺拷貝或東西默認情況下,一切都指向同一個地址

最可能的原因是,你存儲函數局部變量的地址。

face.firstEdge = &edge; 

如果edge是一個函數的局部變量,並調用該函數在一個循環中,它是最有可能會使用相同的堆棧幀,因此最終使用相同的地址。

如果你這樣做,知道你的程序是未定義的行爲。您需要分配給face.firstEdge指向堆中分配的內存的指針。類似於

face.firstEdge = new Edge(edge); 
+1

要小心內存管理,你可能很容易得到內存泄漏。使用智能指針。 http://en.cppreference.com/w/cpp/memory – Ramon

0

循環中聲明的變量每次循環時都會構造並銷燬 - 它們是堆棧中的變量。您不能保存指向這些的指針,當您離開示波器時它們將變爲無效。

您需要使用new/new[]或智能指針在堆上分配變量 - 如R Rahu解釋的那樣。如果對象不包含資源,則最好存儲值,而不是指針。

std::vector< int* > vec; 
    //(...) 
    { 
     int outside_loop = 0; 
     for (int i = 0; i < 2; i++) { 
      int inside_loop = 0; //constructed 
      outside_loop = 0; //new assignment, still refering to the same variable 
      int* heap_var = new int(0); //on heap 

      vec.push_back(&inside_loop); 
      vec.push_back(&outside_loop); 
      vec.push_back(heap_var); //good, variable is on heap 
     }//inside_loop destroyed 

     //vec[0], vec[3] point to variables that no longer exist, they are destroyed at the end of the loop 
     //vec[1] == vec[4] both point to outside_loop, still on stack 
     //vec[2], vec[5] good, each points to a unique variable on heap, which isn't destroyed until delete is called 
    }//outside_loop is destroyed 

//vec[1], vec[4] are now invalid, outside_loop was destroyed 

我測試了上面的代碼,和vec[0] & vec[3]有相同的地址。這是因爲循環中的inside_loop在堆棧中的相同位置創建。此外,它包含一個初始化值0,因爲inside_loop此前已初始化並且該地址尚未使用;這可能就是爲什麼你在你的代碼中看到它們具有相同的值 - 它是內存中的相同地址,保存了最後一個變量的值。當新變量被壓入堆棧時,將使用該地址。永久(左值)引用和指向堆棧變量的指針是一個很大的「否」。