Python 为什么我不需要释放这个内存?
我正在编写Python C扩展,在列出的示例中,有一段代码:Python 为什么我不需要释放这个内存?,python,c,memory-leaks,Python,C,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
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”指向的内存呢?内存泄漏是如何不发生的?对PyArg\u语法元组的“s”格式说明符进行了说明:
s
(字符串或Unicode)[const char*]
将Python字符串或Unicode对象转换为指向字符串的C指针。不能为字符串本身提供存储空间;指向现有字符串的指针存储在您传递其地址的字符指针变量中
这意味着指针指向Python本身正在管理的内存
如果深入研究Python源代码(我使用的是3.2版),您将在Python/getargs.c
中找到PyArg\u ParseTuple
。如果您跟踪执行(如果您已经知道C,一个mark-I眼球应该足够了),您将看到convertsimple
,它处理一些简单的数据类型格式字符串(例如“s”)。然后查看开关的's'
分支,您将看到以下内容:
char **p = va_arg(*p_va, char **);
/* ... */
*p = PyBytes_AS_STRING(uarg);
稍微大一点就会将PyBytes\u定义为\u STRING
:
#define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \
(((PyBytesObject *)(op))->ob_sval))
因此,所有这一切真正要做的就是给你一个指向Python对象内部的字段的指针,ob_sval
;Python正在管理其内部对象的内存
因此,您不应该释放命令
字符串,因为它最终指向Python的一些内部数据,而Python本身负责该内存。因此,文档中出现了“请勿插手”警告。它说Python在哪里释放内存?我假设您完成后需要释放它,当它显示“指向现有字符串的指针”时,我假设PyArq_ParseTuple不分配内存。虽然这不是一个安全的假设,但我会检查文档。@delnan我也是这么想的,但是当我尝试释放内存时,我发现***glibc检测到***python:munmap_chunk():无效指针:0x0000000001ef16dc***@Thiago在这种情况下,如果我继续运行spam_系统,我最终会不会耗尽内存?是的,正如刚才回答的,没有额外的内存被分配。该函数返回一个指向先前分配的对象(args参数)的指针。感谢@mu,我本应该仔细研究源代码来找到它out@Andrew:我怀疑它会归结为类似于PyBytes\u AS\u STRING
,我主要是在验证我的猜测。很高兴能提供帮助。Python什么时候真正开始释放内存?它是否知道我们正在进行函数调用,一旦函数返回,它就可以释放内存?@MatthewMoisen我猜有一个垃圾收集系统用于PyBytesObject
。