I'm trying to access a double* pointer in C++ from python by casting it to a numpy array using PyArray_SimpleNewFromData. However, doing so in C++ results in a memory leak, while doing so in Cython doesn't.
Here is how I do it in C++:
PyObject* IClpSimplex::getReducedCosts(){
npy_intp dims = getNumCols() + getNumRows();
PyObject *Arr = PyArray_SimpleNewFromData( 1, &dims, NPY_DOUBLE, this->djRegion() );
return Arr;
}
In Cython, I call the C++ function to get the PyObject* and cast it to an np array:
cpdef getReducedCosts(self):
return <np.ndarray>self.CppSelf.getReducedCosts()
Here is how I do it in Cython:
cpdef getReducedCosts(self):
cdef np.npy_intp dims = <np.npy_intp> (self.nCols + self.nRows)
cdef double* ptr = <double*> self.CppSelf.djRegion()
return np.PyArray_SimpleNewFromData(1, &dims, np.NPY_DOUBLE, ptr)
return arr
When I looked at the C++ files generated from the Cython code, I found that if I use PyArray_SimpleNewFromData in C++, it Py_INCREF's but doesn't DECREF one of the variables, while for Cython it does:
Cython:
__Pyx_XDECREF(__pyx_r);
__pyx_t_3 = PyArray_SimpleNewFromData(1, (&__pyx_v_dims), NPY_DOUBLE, __pyx_v_ptr); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 480, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_r = __pyx_t_3;
__pyx_t_3 = 0;
...
__Pyx_XDECREF(__pyx_t_3);
C++:
__Pyx_XDECREF(__pyx_r);
__pyx_t_5 = __pyx_v_self->CppSelf->getReducedCosts();
__Pyx_INCREF(((PyObject *)((PyArrayObject *)__pyx_t_5)));
__pyx_r = ((PyObject *)__pyx_t_5);
and there is no __Pyx_XDECREF(__pyx_t_5);
Is this a bug? Or am I missing something in my C++ code? Why would there be a Py_INCREF but not a DECREF?