2011-04-09 83 views
1

我正在寫一個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

回答

5

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

相關問題