cmake-build-extension
cmake-build-extension copied to clipboard
Would SWIG example `normalize_numpy` leak memory?
Here's a quote from the wrapper in bindings_swig/bingins.i
:
void normalize_numpy(double* in_1, unsigned size_in_1,
double** out_1, int* size_out_1)
{
const std::vector<double> vector(in_1, in_1 + size_in_1);
auto result = mymath::normalize(vector);
*out_1 = static_cast<double*>(malloc(result.size() * sizeof(double)));
std::copy(result.begin(), result.end(), *out_1);
*size_out_1 = result.size();
}
I can see malloc
. The question is when the vector is going to be deallocated on the Python side? Or would numpy
do it implicitly (perhaps using Python's GC)?
@adamryczkowski There won't be any leak.
normalize_numpy()
is using the numpy typemap on line 45, which defines the output variable as an ARGOUTVIEWM_ARRAY1
— the M
after ARGOUTVIEW
stands for "Managed", and tells SWIG to not only create the returned Python object from the allocated C++ object's memory directly, without copying it (ARGOUTVIEW
), but also to take ownership of that underlying object, and deallocate it once the Python object is deleted and it's no longer required (ARGOUTVIEWM
).
A list of the available typemaps with very minimal descriptions is in the numpy documentation for numpy.i
, and the more-explanatory blog post dead-linked there can be read using the wayback machine.
(Actually, perhaps more informative is the SciPy Cookbook entry that was created, along with the typemaps in question, based on the automatic deallocation code originally published in that blog post.)