与向量的浅拷贝

时间:2016-03-03 05:33:14

标签: c++

在向量中存储指针对象时遇到问题。 我存储的值如下:

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

其中face.edge是指向其他对象的指针。 我的向量声明为std::vector<Face> all_faces;,结构为:

struct Face{
    Edge* firstEdge
}

当我稍后查看我的元素时,它们都具有相同的价值

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

我知道C ++编译器默认情况下会生成一个浅表副本,而且所有内容都指向同一个地址,我不希望这样。

编辑:Edge是每次循环时声明和修改的局部变量Edge edge = {};

2 个答案:

答案 0 :(得分:1)

  

我知道C ++编译器默认情况下会生成一个浅表副本,而且所有内容都指向同一个地址

最可能的原因是您正在存储函数局部变量的地址。

face.firstEdge = &edge;

如果edge是函数局部变量,并且您在循环中调用该函数,则很可能使用相同的堆栈帧,因此最终使用相同的地址。

如果您这样做,请知道您的程序受到未定义的行为。您需要为face.firstEdge指定一个指向堆上分配的内存的指针。像

这样的东西
face.firstEdge = new Edge(edge);

答案 1 :(得分:0)

循环中声明的变量在每次循环时都被构造和销毁 - 它们是堆栈中的变量。您无法保存指向这些的指针,当您离开范围时它们将变为无效。

你需要在堆上分配变量 - 正如R Rahu所解释的那样 - 使用new/new[]或智能指针。如果对象不保存资源,则最好存储值,而不是指针。

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