为什么我不需要释放这个内存?

问题描述:

我正在写一个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如何知道“command”指向的内存何时可以被释放?如何不发生内存泄漏?

+0

它说Python在哪里释放内存本身?我假设你完成后需要释放它。 – delnan 2011-04-09 17:27:26

+2

当它说“一个指向现有字符串的指针”我假设PyArq_ParseTuple不分配内存。虽然不是一个安全的假设,但我会检查文档。 – 2011-04-09 17:54:50

+0

@delnan这是我的想法,但当我尝试释放内存时,我得到*** glibc检测到*** python:munmap_chunk():无效指针:0x0000000001ef16dc *** – amoffat 2011-04-09 18:04:32

documentation说这大约的 “S” 格式说明PyArg_ParseTuple

s(字符串或Unicode)为const char *]
转换一个Python字符串或Unicode对象C指针到字符串。您不得为字符串本身提供存储空间;指向现有字符串的指针将存储到您传递的地址的字符指针变量中。

这意味着指针指向Python本身正在管理的内存。

如果您深入了解Python源代码(我正在使用3.2版本),您会在中找到PyArg_ParseTuple。如果您追踪执行(如果您已经知道C,则标记 - 我的眼球应该是足够的),您将获得处理一些简单数据类型格式字符串(如“s”)的convertsimple。再看看在交换机的's'分支,你会看到这一点:

char **p = va_arg(*p_va, char **); 
/* ... */ 
*p = PyBytes_AS_STRING(uarg); 

还有一点grepping将产生PyBytes_AS_STRING定义:

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

所以这一切都是真的做的是给你一个指向Python对象内的字段ob_sval的指针; Python正在管理其内部对象的内存。

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

+0

谢谢@mu,我应该想通过源头挖掘出来找出它 – amoffat 2011-04-09 19:16:37

+0

@Andrew:我怀疑它会下降到像'PyBytes_AS_STRING',我主要是验证我的猜测。无论如何,很乐意提供帮助。 – 2011-04-09 19:56:40