带矢量的浅拷贝

Shallow copy with vector

本文关键字:浅拷贝      更新时间:2023-10-16

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

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 = {};每次在循环中声明和修改。

我知道C++编译器默认制作一个浅拷贝或其他东西,并且所有内容都指向相同的地址

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

face.firstEdge = &edge;

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

如果您正在这样做,请知道您的程序受到未定义行为的影响。您需要为face.firstEdge分配一个指针,该指针指向堆上分配的内存。类似的东西

face.firstEdge = new Edge(edge);

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

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