删除 boost::python 公开的 std::vector 中的指针
delete a pointer in std::vector exposed by boost::python
我有这两个类:
typedef std::vector<Entity *> EntityPtrVector;
class A
{
private:
EntityPtrVector entity_vector;
public:
void AddEntity(Entity *);
void RemoveEntity(std::string);
};
class Entity
{
private:
std::string name_;
public:
Entity();
Entity(std::string);
std::string GetName(void) const { return name_; }
void SetName(const std::string& name) { name_ = name; }
};
我通过 boost::python 像这样公开它们:
BOOST_PYTHON_MODULE(my_lib)
{
using namespace boost::python;
class_<EntityPtrVector>("EntityPtrVector")
.def(vector_indexing_suite<EntityPtrVector>());
class_<A>("A", init<std::string>())
.def("AddEntity", &A::AddEntity)
.def("RemoveEntity", &A::RemoveEntity)
;
class_<Entity>("Entity", init<std::string>())
.add_property("name", &Entity::GetName, &Entity::SetName)
;
}
AddEntity
和RemoveEntity
的实现是:
void Game::AddEntity(Entity *E)
{
entity_vector.push_back(E);
}
void Game::RemoveEntity(std::string entity_name)
{
EntityPtrVector::iterator entity_ptr;
// Find the entity with the input name
for(entity_ptr = entity_vector.begin(); entity_ptr != entity_vector.end(); ++entity_ptr)
{
if((*entity_ptr)->GetName() == entity_name)
{
break;
}
}
// Remove the target entity
if(entity_ptr != entity_vector.end())
{
delete *entity_ptr;
entity_vector.erase(entity_ptr);
}
}
我已经检查过它可以在 C++ 下工作而没有暴露给 python。在python中,AddEntity
和查找目标实体的部分是成功的,但是它在RemoveEntity
的delete *
指令处崩溃(我通过在每行之后添加日志指令来检查这些的代码)。这是我在 python:
中的测试代码
import my_lib
test_a = my_lib.A("Test A")
test_e = my_lib.Entity("Test Entity")
test_a.AddEntity(test_e)
test_a.RemoveEntity("Test Entity")
我想也许我 std::vector<Entity *>
的曝光不正确,但我该如何纠正呢?
test_e = my_lib.Entity("Test Entity")
创建一个拥有 C++ Entity
的 Python 对象。它管理生命周期。
test_a.AddEntity(test_e)
这里我们将test_e
包裹的C++对象传递给test_a
包裹的C++对象。 C++ 对象存储在 A
.
的向量中
test_a.RemoveEntity("Test Entity")
这会删除您在上面添加的 Entity
。但是,test_e
class * 仍然认为它拥有 Entity
,因为没有办法告诉它您已转让所有权。但现在它拥有一个无效指针。
崩溃发生在删除时,因为 C++ 不管理该内存 -- python 是。它不使用 C++ 堆。
您需要在 C++ 代码中对所有权和生命周期管理进行更严格的设计。永远不要 delete
你没有 new
的东西,并且 python 案例中的 C++ 代码永远不会 new
编辑 Entity
.
我有这两个类:
typedef std::vector<Entity *> EntityPtrVector;
class A
{
private:
EntityPtrVector entity_vector;
public:
void AddEntity(Entity *);
void RemoveEntity(std::string);
};
class Entity
{
private:
std::string name_;
public:
Entity();
Entity(std::string);
std::string GetName(void) const { return name_; }
void SetName(const std::string& name) { name_ = name; }
};
我通过 boost::python 像这样公开它们:
BOOST_PYTHON_MODULE(my_lib)
{
using namespace boost::python;
class_<EntityPtrVector>("EntityPtrVector")
.def(vector_indexing_suite<EntityPtrVector>());
class_<A>("A", init<std::string>())
.def("AddEntity", &A::AddEntity)
.def("RemoveEntity", &A::RemoveEntity)
;
class_<Entity>("Entity", init<std::string>())
.add_property("name", &Entity::GetName, &Entity::SetName)
;
}
AddEntity
和RemoveEntity
的实现是:
void Game::AddEntity(Entity *E)
{
entity_vector.push_back(E);
}
void Game::RemoveEntity(std::string entity_name)
{
EntityPtrVector::iterator entity_ptr;
// Find the entity with the input name
for(entity_ptr = entity_vector.begin(); entity_ptr != entity_vector.end(); ++entity_ptr)
{
if((*entity_ptr)->GetName() == entity_name)
{
break;
}
}
// Remove the target entity
if(entity_ptr != entity_vector.end())
{
delete *entity_ptr;
entity_vector.erase(entity_ptr);
}
}
我已经检查过它可以在 C++ 下工作而没有暴露给 python。在python中,AddEntity
和查找目标实体的部分是成功的,但是它在RemoveEntity
的delete *
指令处崩溃(我通过在每行之后添加日志指令来检查这些的代码)。这是我在 python:
import my_lib
test_a = my_lib.A("Test A")
test_e = my_lib.Entity("Test Entity")
test_a.AddEntity(test_e)
test_a.RemoveEntity("Test Entity")
我想也许我 std::vector<Entity *>
的曝光不正确,但我该如何纠正呢?
test_e = my_lib.Entity("Test Entity")
创建一个拥有 C++ Entity
的 Python 对象。它管理生命周期。
test_a.AddEntity(test_e)
这里我们将test_e
包裹的C++对象传递给test_a
包裹的C++对象。 C++ 对象存储在 A
.
test_a.RemoveEntity("Test Entity")
这会删除您在上面添加的 Entity
。但是,test_e
class * 仍然认为它拥有 Entity
,因为没有办法告诉它您已转让所有权。但现在它拥有一个无效指针。
崩溃发生在删除时,因为 C++ 不管理该内存 -- python 是。它不使用 C++ 堆。
您需要在 C++ 代码中对所有权和生命周期管理进行更严格的设计。永远不要 delete
你没有 new
的东西,并且 python 案例中的 C++ 代码永远不会 new
编辑 Entity
.