From 782b690ed7ea33556e96f9e19d60846af4507146 Mon Sep 17 00:00:00 2001 From: Ben Frederickson Date: Mon, 11 Dec 2017 11:05:26 -0800 Subject: [PATCH] Fix Memory Leak in Python Bindings. The default return_value_policy for py::cast calls is return_value_policy::automatic_reference (as described here: http://pybind11.readthedocs.io/en/stable/advanced/functions.html#return-value-policies). This means that pybind was treating the index as a reference, and not taking ownership of it and calling the desctructor when the python object was freed. Fix by explicitly telling pybind to take ownership here. --- python_bindings/nmslib.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/python_bindings/nmslib.cc b/python_bindings/nmslib.cc index e24edfa..8b4c281 100644 --- a/python_bindings/nmslib.cc +++ b/python_bindings/nmslib.cc @@ -305,6 +305,7 @@ struct IndexWrapper { } ~IndexWrapper() { + LOG(LIB_DEBUG) << "Destroying Index"; freeObjectVector(&data); } @@ -386,17 +387,17 @@ PYBIND11_PLUGIN(nmslib) { switch (dtype) { case DISTTYPE_FLOAT: { auto index = new IndexWrapper(method, space, space_params, data_type, dtype); - ret = py::cast(index); + ret = py::cast(index, py::return_value_policy::take_ownership); break; } case DISTTYPE_DOUBLE: { auto index = new IndexWrapper(method, space, space_params, data_type, dtype); - ret = py::cast(index); + ret = py::cast(index, py::return_value_policy::take_ownership); break; } case DISTTYPE_INT: { auto index = new IndexWrapper(method, space, space_params, data_type, dtype); - ret = py::cast(index); + ret = py::cast(index, py::return_value_policy::take_ownership); break; } default: