确保 vector 中的共享指针被正确推回

Ensuring shared pointers within vector are pushed back properly

我可能在这方面有一些错误,这真的是我第一次特别处理共享指针。

我正在研究遍历一棵树。我的树由一个链表组成,带有一个共享指针向量,代表每个节点的所有 children。为了遍历,我(首先)尝试这样做:

//--------------------------------------------------------------
void setupMesh(){
    Mesh mesh;

    shared_ptr<Mesh> shared_mesh(&mesh);
    meshes.push_back(shared_mesh);

    checkChildren(root, &temp_mesh);
}

//--------------------------------------------------------------
void checkChildren(Node * temp_node, Mesh * temp_mesh){

    if(!temp_node->children.empty()){
        for(int i = 0; i < temp_node->children.size(); i++){
            if(i > 0){
                shared_ptr<Mesh> new_mesh(new Mesh);
                meshes.push_back(new_mesh);
            }

            temp_node = temp_node->children[0].get();
            checkChildren(temp_child, temp_mesh);
        }
    }  
}

我的树结构本身看起来不错,但更多的问题在于我如何遍历它,以及我如何跟踪指针。它当前正在返回错误的访问错误。据我所知,我正在插入一个指向临时 object、temp_node 和 temp_mesh.

的指针

为了简化我想到的过程:

遍历属于节点[0](根)的所有children。 对于 children 中的每一个,对它们执行相同的循环。如果 child 是 child[0],继续将它的坐标添加到相同的 temp_mesh object,但如果它是另一个 child,则创建一个新网格存储它,并且首先 children 。 任何新的网格都应该有一个指针被推回网格矢量 (vector>)。

有没有人建议我如何更有效地执行此操作,或者我在处理内存中的这些指针时出了什么问题。

It is currently returning bad access errors.

那这就是你最应该担心的事情。这是一个严重的错误。

From what I can tell, it looks like I am inserting a pointer to a temporary object, temp_node, and temp_mesh.

这不是 "temporary" 对象,这意味着不同的东西(为什么你继续在你的变量名中使用 "temp"?),但你对问题的看法是对的:

shared_ptr<ofMesh> shared_mesh(&temp_mesh);

这将创建一个 shared_ptr,它 拥有 指针 &temp_mesh,因此当没有更多 shared_ptr 对象共享时将删除它该指针的所有权。

但是那个指针是一个自动变量(又名堆栈变量)的地址,它在块的末尾超出范围。您不 "own" 该对象,该函数的块作用域会自动管理它。如果您不拥有它,那么您不能将它的所有权授予 shared_ptr,因为它不属于您。

当作用域结束时,自动变量 temp_mesh 将被自动销毁,但仍有 shared_ptr 持有该指针的对象,认为它们拥有它。当您尝试通过那些 shared_ptr 对象访问该对象时,您会在其生命周期结束后访问一个已销毁的对象。然后,当不再有 shared_ptr 个对象拥有该指针时,它将被删除,但它不是用 new 创建的,所以这是一个严重的错误。 (你在另一个函数中做对了,所以我不确定你为什么在 setupMesh 中做错了)。

如果您想让 shared_ptr 拥有一个对象,您需要使用 new 创建它,或者最好使用 std::make_shared 创建它:*

shared_ptr<ofMesh> mesh = std::make_shared<ofMesh>();
mesh0->setMode(OF_PRIMITIVE_LINE_STRIP);
mesh->setupIndicesAuto();
mesh->addVertex(root->location);
mesh->addColor(ofColor(0));

meshes.push_back(shared_mesh);

checkChildren(root, mesh.get());

这会立即创建一个由 shared_ptr 拥有的对象,因此转移 shared_ptr 不能拥有的东西的所有权没有问题。


* 或者您可以使用 "null deleter" 但这对于这个答案来说太高级了,并且不能像这样使用自动变量。