Python CFFI `<cdata>` 数据指针替换来自 C 语言 - 安全吗?

问题描述 投票:0回答:1

我正在尝试使用 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
  • 这样做安全吗?
  • 我需要担心指针数据所有权或内存泄漏吗?
python c cpython python-cffi
1个回答
0
投票

“保存实际

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()
返回的对象超出范围,该内存就会消失。

© www.soinside.com 2019 - 2024. All rights reserved.