确保 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" 但这对于这个答案来说太高级了,并且不能像这样使用自动变量。
我可能在这方面有一些错误,这真的是我第一次特别处理共享指针。
我正在研究遍历一棵树。我的树由一个链表组成,带有一个共享指针向量,代表每个节点的所有 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" 但这对于这个答案来说太高级了,并且不能像这样使用自动变量。