2017-02-20 78 views
-1

我可能有这个错误的一些方面,这实际上是我第一次特别用共享指针进行处理。确保向量中的共享指针被正确推回

我正在穿越一棵树。我的树由一个链表组成,其中有一个共享指针向量,代表每个节点的所有子对象。要遍历,我(与开始)试图做到这一点:

//-------------------------------------------------------------- 
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); 
     } 
    } 
} 

我的树结构本身似乎不错,但它与我如何穿越它,以及如何我跟踪的更多问题指针。它目前正在返回错误的访问错误。从我可以告诉,它看起来像我插入一个指向临时对象,temp_node,和temp_mesh的指针。

为了简化这一过程我想到:通过属于节点[0](根)的所有儿童

环路。 对于每个孩子,对他们执行相同的循环。如果孩子是[0]孩子,继续添加它的坐标到同一个temp_mesh对象,但如果它是另一个孩子,创建一个新的网格来存储它,并且它的所有第一个孩子。 任何新的网格应该有一个指针推回到网格矢量(vector>)。

有没有人有关如何更有效地做到这一点,或者我在处理内存中的这些指针时出错的建议。

+0

请将[编辑]下拉到[mcve],而不是(看上去像)完整的代码 - 即删除无关的代码,直到获得最短可读的,可编译的代码位来展示问题。 –

+0

希望现在就足够了! – aceslowman

+0

(这是一个有争议的问题,因为有人回答,但为了完整:)非常接近!添加一个包含_just_的'main'和'Node'和'Mesh'的定义,足以复制该问题。它需要完成 - 也就是说,如果我将您提供的代码复制/粘贴到我的编辑器中,它会编译,运行并演示此问题。我在第一条评论中链接的文章给出了比以往更好的描述。 –

回答

4

它目前返回错误的访问错误。

那么这就是你应该担心的首要任务。这是一个严重的错误。

从我可以告诉,它看起来像我插入一个指向临时对象,temp_node和temp_mesh的指针。

这是不是“临时”的对象,这意味着不同的东西(你为什么一直在使用你的变量名“临时”?),但你说得对这个问题:

shared_ptr<ofMesh> shared_mesh(&temp_mesh); 

这会创建一个shared_ptr,其中拥有指针&temp_mesh,因此将在共享该指针的所有权不再有shared_ptr个对象时删除它。

但是,该指针是一个自动变量(又名堆栈变量)的地址,它在块的末尾超出范围。您不“拥有”该对象,该功能的块范围会自动对其进行管理。如果你不拥有它,那么你不能把它归于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所不具有的东西的所有权不存在任何问题。


*或者你可以使用一个“零缺失者”,但是这对这个答案的方式太先进了,而不会使它OK使用这样的自动变量。

+0

这真是太棒了,你真的帮我清理了一些我对此的理解。它不再抛出任何错误。很明显,我创建的树比我想象的要大得多,所以现在我要解决新的问题了。谢谢! – aceslowman