删除boost :: python暴露的std :: vector中的指针

时间:2015-02-22 02:38:44

标签: python c++ boost stdvector 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)
    ;
}

AddEntityRemoveEntity的实施是:

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的部分和查找目标实体是成功的,但它在delete *的{​​{1}}指令崩溃(我通过在每行代码后添加日志指令来检查这些) 。这是我在python中的测试代码:

RemoveEntity

我想也许我会错误地揭露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") ,但我怎么能纠正这个?

1 个答案:

答案 0 :(得分:1)

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类*仍然认为它拥有Entity,因为没有办法告诉您通过了所有权。但现在它拥有一个无效的指针。

崩溃发生在删除,因为C ++没有管理那个内存 - python是。它不使用C ++堆。

您需要在C ++代码中拥有更完善的所有权和生命周期管理设计。永远不会delete你没有new,而python案例中的C ++代码永远不会new编辑Entity