I have this example code that has a function text()
returning a newly allocated string:
ffi_test = FFI()
ffi_test.set_source('_test', '''
char* test() { return strdup("hello world"); }
''')
ffi_test.cdef('''
char* test();
void free(void *);
''')
ffi_test.compile(verbose=True)
This works fine:
In [1]: from _test import ffi, lib
In [2]: x = lib.test()
In [3]: ffi.string(x)
Out[3]: b'hello world'
In [4]: lib.free(x)
However, I could not find anything in the docs whether I actually need to manually free()
the returned string of if CFFI takes ownership of the pointer as soon as it's returned to Python code.
Also, if I do need to manually free()
it, do I need to expose free()
in my cdefs or is does CFFI provide some nicer way for it?
From the documentation on Working with pointers, structures and arrays, and quoting the correct section:
Therefore you must free it, there is no way it can assume the ownership: In C there are many functions that return a pointer to a constant string in memory, that not only it is not dynamically allocated, it is not allocated, or modifiable at all, for example. Freeing those would be very erroneous.
Also for
free
, the documentation says the following:Since it is very important that the correct C standard library
free
is used for a pointer returned bystrdup
you cannot rely CFFI to magically do the correct thing, but instead as you suspected, you should exposefree()
. You can also use thegc
as suggested by Barmar to register an automatic clean up, if needed: