amo*_*fat 2 c python memory-leaks
我正在编写一个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);
}
Run Code Online (Sandbox Code Playgroud)
根据使用PyArg_ParseTuple解析字符串的文档,"您不能为字符串本身提供存储;指向现有字符串的指针存储在您传递的地址的字符指针变量中." 那么Python如何知道"命令"指向的内存何时可以被释放?如何不发生内存泄漏?
该文件说,这对"S"格式说明PyArg_ParseTuple:
s(字符串或Unicode)[const char*]
将Python字符串或Unicode对象转换为指向字符串的C指针.您不能为字符串本身提供存储空间; 指向现有字符串的指针存储在您传递其地址的字符指针变量中.
这意味着指针指向Python本身正在管理的内存.
如果你深入研究Python源代码(我使用的是3.2版本),你会发现PyArg_ParseTuple它Python/getargs.c.如果你追踪执行(如果你已经知道C,那么标记 - 我的眼球就足够了)你将会convertsimple处理一些简单的数据类型格式字符串(例如"s").然后看一下's'开关的分支,你会看到:
char **p = va_arg(*p_va, char **);
/* ... */
*p = PyBytes_AS_STRING(uarg);
Run Code Online (Sandbox Code Playgroud)
稍微一点点就会产生以下定义PyBytes_AS_STRING:
#define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \
(((PyBytesObject *)(op))->ob_sval))
Run Code Online (Sandbox Code Playgroud)
所以这一切都是ob_sval在Python对象内部给你一个指向字段的指针; Python正在管理其内部对象的内存.
所以,你不应该释放你的command字符串,因为它最终指向Python的一些内部数据,Python本身负责该内存.因此文档中的"手动"警告.