Skip to content

Commit 01481d0

Browse files
Fix memory leak in find_path: use Py_BuildValue N format to transfer ownership
Py_BuildValue with O format increments refcount, but the code then set local pointers to NULL preventing cleanup Py_XDECREF from running, leaving each returned numpy array with a permanent refcount of 1. Switched to N format which transfers ownership without incrementing. Also added missing Py_XDECREF for haplotype_array in AncestorMatcher2.
1 parent 34141a5 commit 01481d0

1 file changed

Lines changed: 3 additions & 2 deletions

File tree

_tsinfermodule.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,7 +1501,7 @@ AncestorMatcher_find_path(AncestorMatcher *self, PyObject *args, PyObject *kwds)
15011501
memcpy(PyArray_DATA(left), ret_left, num_edges * sizeof(*ret_left));
15021502
memcpy(PyArray_DATA(right), ret_right, num_edges * sizeof(*ret_right));
15031503
memcpy(PyArray_DATA(parent), ret_parent, num_edges * sizeof(*ret_parent));
1504-
ret = Py_BuildValue("(OOO)", left, right, parent);
1504+
ret = Py_BuildValue("(NNN)", left, right, parent);
15051505
if (ret == NULL) {
15061506
goto out;
15071507
}
@@ -1939,7 +1939,7 @@ AncestorMatcher2_find_path(AncestorMatcher2 *self, PyObject *args, PyObject *kwd
19391939
goto out;
19401940
}
19411941
ret = Py_BuildValue(
1942-
"(kOOOO)", (unsigned long) num_edges, left, right, parent, match);
1942+
"(kNNNN)", (unsigned long) num_edges, left, right, parent, match);
19431943
if (ret == NULL) {
19441944
goto out;
19451945
}
@@ -1948,6 +1948,7 @@ AncestorMatcher2_find_path(AncestorMatcher2 *self, PyObject *args, PyObject *kwd
19481948
parent = NULL;
19491949
match = NULL;
19501950
out:
1951+
Py_XDECREF(haplotype_array);
19511952
Py_XDECREF(match);
19521953
Py_XDECREF(left);
19531954
Py_XDECREF(right);

0 commit comments

Comments
 (0)