我正在尝试使用 CFFI 创建 python C 扩展。
假设我有以下 C 代码:
void freeSomeType(SomeType_t **ptr)
{
free(*ptr);
*ptr = NULL;
}
void func(SomeType_t **ptr)
{
freeSomeType(ptr);
*ptr = malloc(...);
}
然后,假设我从 python land 中调用它,如下所示:
ptr = ffi.new("SomeType_t **")
# Init and do stuff with ptr...
lib.func(ptr)
本质上,在
SomeType **
的 ptr
对象中保存实际 cdata
数据的指针已经改变了它的值。如果我这样做会发生什么:
lib.freeSomeType(ptr)
del ptr
“保存实际
SomeType **
数据(...)的指针已更改”:不,唯一更改的指针是 SomeType *
类型。 在CFFI中,如果你分配了ptr = ffi.new("SomeType **")
,那么你得到的SomeType **
就不能改变。 它始终指向相同的内存,该内存本身只是指针大小并保存一个 SomeType *
指针。 这就是可以改变的内存——这就是调用 lib.func()
所做的事情。
在我看来,您建议的代码是正确的。 这样做是安全的,不会造成内存泄漏。 内存所有权取决于上下文,但这似乎也是正确的。 最后的
del ptr
在 Python 中影响不大,可以省略:当 Python 不再引用 ptr
对象时,它将释放它指向的(指针大小的)内存。
如果你忘记调用
lib.freeSomeType()
,那么确实存在泄漏,因为C代码调用了malloc()
,但从未调用过相应的free()
。 这是您唯一需要担心的泄漏; Python 中的 ffi.new()
分配由 Python 管理的内存,如果 ffi.new()
返回的对象超出范围,该内存就会消失。