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

Alexis H. Rivera-Rios ahrivera at yahoo.com
Tue Nov 23 07:56:04 CET 2004


Hi, 

I'm writing some dummy classes to learn how to create
Python classes that are derived from C++ classes. I
have the following class:

class Strategy
{
public:
	virtual ~Strategy() {};
	virtual void Execute() = 0;

};

I want to derive classes from that class using Python
to then send them to this other class:

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(); }
};

I exposed the classes doing the following:
struct StrategyWrap : Strategy, wrapper<Strategy>
{
public:
    void Execute()
    {
        this->get_override("Execute")();
    }
};

BOOST_PYTHON_MODULE(libhello)
{

	class_<StrategyWrap, boost::noncopyable>("Strategy")
    .def("Execute", pure_virtual(&Strategy::Execute))
    ;

	class_<MutableObject>("MutableObject")
    .def("AddStrategy", &MutableObject::AddStrategy,
with_custodian_and_ward<1,2>())
    .def("GetNumStrategies",
&MutableObject::GetNumStrategies)
    .def("SelectStrategy",
&MutableObject::SelectStrategy)
    .def("ExecuteStrategy",
&MutableObject::ExecuteStrategy)
	;
}

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.
 At least, that is my goal. 

I tested the code with the following script:
from libhello import *

class NewStrat(Strategy):
	def Execute(self):
		print "Another message"

x = MutableObject()

for i in xrange(0,x.GetNumStrategies()):
	x.SelectStrategy(i)
	x.ExecuteStrategy()

y = NewStrat()
x.AddStrategy(y)

for i in xrange(0,x.GetNumStrategies()):
	x.SelectStrategy(i)
	x.ExecuteStrategy()

I get the following error when I execute the script
above:
nothing to do here
nothing to do here
Another message
free(): invalid pointer 0x807f420! <---

All I can deduce is that either the object is being
delete twice. Or the Python object was created using
malloc() and my C++ code tries to delete it using
delete and that's why I get this error.

Is my theory correct? How do I go about fixing it?

I will appreciate your help.
Alexis


=====
Programming Tutorial:
In Python: To do this, do this
In Perl: To do this, do this or this or this or this...
In C: To do this, do this, but be careful
In C++: To do this, do this, but don't do this, be careful of this, watch out for this, and whatever you do, don't do this


		
__________________________________ 
Do you Yahoo!? 
The all-new My Yahoo! - Get yours free! 
http://my.yahoo.com 
 




More information about the Cplusplus-sig mailing list