[capi-sig] Naive question on references

Gustavo Carneiro gjcarneiro at gmail.com
Thu Aug 13 10:49:04 CEST 2009


2009/8/13 Jérôme Fuselier <jerome.fuselier at free.fr>

>
>
> Gustavo Carneiro wrote:
>
>
>
> 2009/8/12 Jérôme Fuselier <jerome.fuselier at 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


More information about the capi-sig mailing list