[C++-sig] question about implicit type conversion of vector to a custom type

Jim Bosch talljimbo at gmail.com
Thu Aug 18 19:44:02 CEST 2011


On 08/18/2011 09:37 AM, Grant Tang wrote:
>
> I change my vector<> conversion(see it in my last reply) to add
> specialization for int, float, string etc.
> I added type check in convertible() function:
>

Sorry I didn't reply to your last email earlier, but it looks like 
you're on the right track.

Here's a slightly modified version of your convertible function:

static void* convertible(PyObject* obj_ptr)
{
   // Unfortunately, this no longer works on pure iterators, because
   // they don't necessarily support "obj[0]".
   // PySequence_Check should work on lists, tuples, and other
   // things that support __getitem__ with integer arguments.
   if (!(PySequence_Check(obj_ptr)) {
     return 0;
   }
   // Succeed if there are no items in the sequence.
   if (PySequence_Size(obj_ptr) == 0) {
     return obj_ptr;
   }
   // PySequence_GetItem takes an int directly; otherwise you'd need
   // to DECREF the int object you pass to PyObject_GetItem as well.
   PyObject * first_obj = PySequence_GetItem(obj_ptr, 0);
   if( !PyObject_TypeCheck(first_obj, &PyFloat_Type) ) {
     Py_DECREF(first_obj); // avoid memory leaks on failure
     return 0;
   }
   Py_DECREF(first_obj); // avoid memory leaks on success
   return obj_ptr;
}

> This time the implicit type conversion works perfectly. But I got a new
> problem: the memory leak!
> The memory leak happens only for float type, whenever I convert the
> float list in python to vector
> of float in c++, the memory for float list is leaked. I put the call in
> a function, and called the gc.collect()
> after exit the function, the memory is still not recycled.
>
> Why is the memory of the python list is not freed after exit the scope?
>

It's the missing Py_DECREF calls; it's only because of a Python 
implementation detail that you didn't have leaks with the other types. 
The Python C-API requires you to call Py_DECREF whenever you're done 
with an object.  Alternately, you can put your PyObject pointers in 
bp::handle<> or bp::object, and they'll be managed automatically.

Jim



More information about the Cplusplus-sig mailing list