1

https://github.com/python/cpython/blob/master/Include/objimpl.h#L83 says

PyObject_Realloc(p != NULL, 0) does not return NULL, or free the memory at p.

PyObject_Realloc doesn't free the memory.

I've noticed a memory leak in my program which uses PyObject_Realloc every now and then.

I tried to fix it using this:

PyLongObject *new = (PyLongObject *) PyObject_Realloc(obj, new_size);
if (new == NULL) {
  return PyErr_NoMemory();
}
if (new != obj) {
  PyObject_Free(obj);
}
obj = new;

But now I get the malloc error pointer being freed was not allocated

How am I meant to make sure my program doesn't leak memory when using PyObject_Malloc and PyObject_Realloc?

theonlygusti
  • 11,032
  • 11
  • 64
  • 119
  • Have you ensured that the reference count of `obj` is 1? If there are other pointers to it in existance then reallocing it isn't going to be safe. – DavidW Mar 23 '21 at 13:01
  • 1
    @DavidW checking `Py_REFCNT(obj)` before every reallocation shows it's always 1 – theonlygusti Mar 23 '21 at 13:28
  • That's fine then. There's definitely cases where this this is reliably true (e.g. you've just allocated an object in C and haven't yet returned it to Python) – DavidW Mar 23 '21 at 13:47
  • @DavidW since I think the memory leak comes from elsewhere, I made a new question with my full code. I wonder if you can spot anything: https://stackoverflow.com/q/66764918/3310334 – theonlygusti Mar 23 '21 at 14:16

1 Answers1

2

You need to use this in the exact same manner as realloc must be used:

PyObject *new = PyObject_Realloc(obj, new_size);

if (new == NULL) {
    // obj is still valid - so maybe you need to free it *here*
    PyObject_Free(obj);
    return PyErr_NoMemory();
}


// if a non-null pointer *was* returned, then obj was already
// freed and new points to the new memory area. Therefore
// assign it to obj unconditionally.
obj = new;