Python 我需要释放通过CFFI调用的C函数返回的内存吗?

Python 我需要释放通过CFFI调用的C函数返回的内存吗?,python,c,memory-management,free,python-cffi,Python,C,Memory Management,Free,Python Cffi,我有一个示例代码,其中有一个函数text()返回一个新分配的字符串: 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) 这很好: In [1]: from _test i

我有一个示例代码,其中有一个函数
text()
返回一个新分配的字符串:

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)
这很好:

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)
然而,我在文档中找不到任何东西,无论我是否真的需要手动
free()
返回的字符串if CFFI在指针返回到Python代码后立即获得指针的所有权

另外,如果我确实需要手动
free()
它,我是否需要在我的cdefs中公开
free()
,或者CFFI是否提供了更好的方法?

从上的文档中,并引用正确的部分:

任何在C中返回指针、数组或结构类型的操作都会为您提供一个新的cdata对象与“原始”对象不同,这些新的cdata对象没有所有权

因此,您必须释放它,它无法承担所有权: 在C语言中,有许多函数返回指向内存中常量字符串的指针,例如,它不仅没有动态分配,也没有分配,或者根本不可修改。释放这些人将是非常错误的


对于
免费
,文档说明如下:

另一种方法是声明和调用C malloc()和free()函数,或者一些变量,如mmap()和munmap()。然后您可以精确地控制内存的分配和释放时间。例如,将这两行添加到现有的ffibuilder.cdef()中:

由于将correctC标准库
free
用于
strdup
返回的指针非常重要,因此您不能依靠CFFI神奇地执行正确的操作,但正如您所怀疑的那样,您应该公开
free()
。如果需要,您还可以按照Barmar的建议使用
gc
,注册自动清理:

x = ffi.gc(x, lib.free)

当对象的“所有权”从一个软件组件传递到另一个软件组件时,新所有者将负责释放内存。因为这就是“所有权”的意思。谢谢!这就是我错过的文档中的部分。现在只剩下第二部分了——也就是说,我是否需要像上面那样公开
free()
,或者如果CFFI自动这样做(
lib.free
不存在,但如果我不在我的cdef中手动公开它),如果您知道对象是动态分配的
malloc()
,您可以使用
ffi.gc()
注册
lib.free
回收。
x = ffi.gc(x, lib.free)