我为什么不需要释放这个内存?
我正在写一个Python的C扩展,在这里的例子中有一段代码:
static PyObject * spam_system(PyObject *self, PyObject *args) {
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command)) return NULL;
sts = system(command);
return Py_BuildValue("i", sts);
}
根据文档中关于使用PyArg_ParseTuple解析字符串的说明,“你不需要为字符串本身提供存储空间;你只需要传递一个指向已有字符串的指针,Python会把这个指针存储到你传入的字符指针变量中。”那么,Python是怎么知道“command”指向的内存什么时候可以释放的呢?这样不会出现内存泄漏吗?
1 个回答
10
文档中提到关于 PyArg_ParseTuple
的 "s" 格式说明:
s
(字符串或Unicode) [const char *]
将一个Python字符串或Unicode对象转换为C语言中的字符字符串指针。你不需要为这个字符串本身提供存储空间;你只需将一个已存在字符串的指针传递给这个字符指针变量。
这意味着这个指针指向的是Python自己管理的内存。
如果你深入查看Python的源代码(我用的是3.2版本),你会在 Python/getargs.c
中找到 PyArg_ParseTuple
。如果你跟踪执行过程(如果你已经懂C语言,肉眼观察就够了),你会看到 convertsimple
,它处理一些简单的数据类型格式字符串(比如 "s")。然后看看 's'
的分支,你会看到这个:
char **p = va_arg(*p_va, char **);
/* ... */
*p = PyBytes_AS_STRING(uarg);
再稍微查找一下,你会找到 PyBytes_AS_STRING
的定义:
#define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \
(((PyBytesObject *)(op))->ob_sval))
所以,这一切其实就是给你一个指向Python对象内部字段 ob_sval
的指针;Python负责管理它内部对象的内存。
因此,你不应该释放你的 command
字符串,因为它指向的是Python内部数据的一部分,而Python自己负责那块内存。所以文档中有个“不要动手”的警告。