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

Do I need to free memory returned from a C function called via 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 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 提供一些更好的怎么办?

来自 Working with pointers, structures and arrays 的文档,引用正确的部分

Any operation that would in C return a pointer or array or struct type gives you a fresh cdata object. Unlike the “original” one, these fresh cdata objects don’t have ownership

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


同样对于 free,文档说明如下:

An alternative is to declare and call the C malloc() and free() functions, or some variant like mmap() and munmap(). Then you control exactly when the memory is allocated and freed. For example, add these two lines to your existing ffibuilder.cdef():

void *malloc(size_t size);
void free(void *ptr);

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

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