2009/8/13 Jérôme Fuselier <jerome.fuselier@free.fr>
Gustavo Carneiro wrote:
2009/8/12 Jérôme Fuselier <jerome.fuselier@free.fr>
Hello, I have a working application which extends a C api to python and everything works as I wanted to. I'm now in a cleaning phase where I want to improve my stuff, especially to avoid memory leak.
Here is a simple example of what seems correct to me but for which I would like an expert opinion :
PyObject * test() { PyObject *dict = PyDict_New(); // ... some code to initialize dict
PyObject *item = PyDict_GetItemString(dict, "key"); Py_INCREF(item); Py_DECREF(dict); return item; }
As far as I understood, PyDict_GetItemString() returns a borrowed reference to the element so I need to do Py_INCREF(item) to own this reference. But is this needed ? If I only do return item, will the received item be owned by the caller of the test method ?
Yes, you do need the INCREF. If you remove the Py_INCREF(item) line, then when Py_DECREF(dict) is executed the dictionary could be freed, along with the object pointed to by 'item'.
The code above is correct, and the caller of your test() function is responsible for DECREF'ing the returned value.
Thanks,
That's confirm my understanding so that's fine.
I have another question related to memory management in the python api.
I often see this code :
char *s; ok = PyArg_ParseTuple(args, "s", &s); ..
But I never saw if there's a need/way to free the memory for s. I tried with malloc and PyMem_Free but this leads to segmentation fault. I often have large data passed as parameters, with a process that can last long so I would like to ensure that there's not a memory leak in that part.
No need to free memory for 's'. The string pointer stored in 's' is valid as long as the 'args' reference is valid, but it is a borrowed pointer, bound to the life cycle of 'args'. That is, you can do what you want with 's' but don't keep this pointer beyond the scope where 'args' is defined. If you really need the string beyond this scope, strdup() is your friend.
-- Gustavo J. A. M. Carneiro INESC Porto, Telecommunications and Multimedia Unit "The universe is always one step beyond logic." -- Frank Herbert