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)