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此前已初始化并且该地址尚未使用;这可能就是为什么你在你的代码中看到它们具有相同的值 - 它是内存中的相同地址,保存了最后一个变量的值。当新变量被压入堆栈时,将使用该地址。永久(左值)引用和指向堆栈变量的指针是一个很大的“否”。