2017-02-20 49 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