为什么我不需要释放这个记忆?

时间:2011-04-09 17:25:06

标签: python c memory-leaks

我正在编写一个Python C扩展,在列出的here示例中,有一段代码:

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如何知道“命令”指向的内存何时可以被释放?如何不发生内存泄漏?

1 个答案:

答案 0 :(得分:6)

documentation说明PyArg_ParseTuple的“s”格式说明符:

  

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);

稍微一点点就会产生PyBytes_AS_STRING

的定义
#define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \
                                (((PyBytesObject *)(op))->ob_sval))

所以这一切真的就是在Python对象中向你发送指向字段ob_sval的指针; Python正在管理其内部对象的内存。

所以,你不应该释放你的command字符串,因为它最终指向Python的一些内部数据,而Python本身负责该内存。因此,文档中的“手动”警告。