[C++-sig] Re: understanding pointer ownership with Boost.Python

David Abrahams dave at boost-consulting.com
Tue Nov 23 23:13:41 CET 2004


"Alexis H. Rivera-Rios" <ahrivera at yahoo.com> writes:

> I used the with_custodian_and_ward because my
> intention is to tell boost.python that whatever
> instance is created in python will be owned by the
> MutableObject class.  This class will free the memory.

I'm pretty sure the code you posted can't compile.

  class MutableObject
  {
      std::vector<Strategy *> strategyList;
                  ^^^^^^^^^^
      Strategy *current;

  public:
      MutableObject() {strategyList.push_back(new
  NullStrategy()); SelectStrategy(0); }
      ~MutableObject() { for (int
  i=0;i<strategyList.size();++i) delete strategyList[i];
  }


      void AddStrategy(Strategy *s) {
  strategyList.push_back(s); }
      size_t GetNumStrategies() { return
  strategyList.size(); }
      void SelectStrategy(size_t ith) { current =
  strategyList.at(ith).get(); }
                      ^^^^^^
      void ExecuteStrategy() { current->Execute(); }
  };

So I don't believe you actually tested it.  

Your problem is that the result of NewStrat is a Python object that
owns its C++ Strategy subobject.  You need AddStrategy to assume
ownership, because the MutableObject is going to delete the object
later.  So wrap Strategy using

  class_<Strategy, std::auto_ptr<Strategy>...>  

and build a thin wrapper function for AddStrategy that accepts an
auto_ptr:

  void AddStrategy(MutableObject& m, std::auto_ptr<Strategy> s)
  {
       m.AddStrategy(s.get());
       s.release();
  }

      ...

     .def("AddStrategy", &AddStrategy)
      ...


Incidentally, your AddStrategy is probably not very exception-safe to
begin with.

HTH,

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com




More information about the Cplusplus-sig mailing list