Ctypes结构和指针在Python对象删除时会自动释放内存吗?
在使用Python的CTypes时,有一种叫做结构体的东西,它可以让你在Python中复制C语言的结构体。同时,还有指针对象,它可以根据内存地址创建一个复杂的Python对象,并且可以用来在C代码和Python之间传递对象。
我在文档或者其他地方找不到的信息是,当一个包含结构体的Python对象被删除时,这个结构体是从C代码返回的指针中解引用出来的(也就是说,C函数为这个结构体分配了内存),那么原来的C结构体的内存会被释放吗?如果不会,那该怎么做呢?
另外,如果这个结构体里面还有指向其他数据的指针,而这些数据也是由C函数分配的内存,那么删除这个结构体对象会释放它里面指针指向的内存吗?(我对此表示怀疑)如果不会,那又该怎么处理呢?我尝试从Python中调用系统的“free”来释放结构体中的指针,但这让我Python崩溃了。
换句话说,我有一个通过C函数调用填充的结构体:
class PIX(ctypes.Structure):
"""Comments not generated
"""
_fields_ = [
("w", ctypes.c_uint32),
("h", ctypes.c_uint32),
("d", ctypes.c_uint32),
("wpl", ctypes.c_uint32),
("refcount", ctypes.c_uint32),
("xres", ctypes.c_uint32),
("yres", ctypes.c_uint32),
("informat", ctypes.c_int32),
("text", ctypes.POINTER(ctypes.c_char)),
("colormap", ctypes.POINTER(PIXCOLORMAP)),
("data", ctypes.POINTER(ctypes.c_uint32))
]
我想从Python代码中释放它所占用的内存。
1 个回答
13
内存没有被释放,因为Python不知道该如何释放它。我们来看看这两个函数:
void testfunc1(PIX *pix)
{
static char staticBuffer[256] = "static memory";
pix->text = staticBuffer;
}
void testfunc2(PIX *pix)
{
pix->text = (char *)malloc(32);
strcpy(pix->text, "dynamic memory");
}
用法是这样的:
pix1, pix2 = PIX(), PIX()
mylib.testfunc1(ctypes.byref(pix1))
mylib.testfunc2(ctypes.byref(pix2))
然后在某个时刻,pix1
和 pix2
失去了作用域。当这种情况发生时,内部指针不会有任何变化——如果它们指向动态内存(这里的pix2
就是这样,但pix1不是),那么你就得自己负责释放这部分内存。
解决这个问题的正确方法是,如果你在C代码中分配了动态内存,你应该提供一个相应的函数来释放这部分内存。例如:
void freepix(PIX *pix)
{
free(pix->text);
}
pix2 = PIX()
mylib.testfunc2(ctypes.byref(pix2))
...
mylib.freepix(ctypes.byref(pix2))