我在Python和C中有豐富的經驗,但是對於將C模塊作爲C函數的包裝器件編寫爲新手。對於一個項目,我需要一個名爲「score」的函數,它的運行速度比我能夠在python中獲得的速度快得多,所以我使用C語言編寫了代碼,並且從字面上來說只是想從python中調用它。它需要一個python的整數列表,我希望C函數得到一個整數數組,這個數組的長度,然後返回一個整數回到python。這是我目前的(工作)解決方案。Python C包裝內存泄漏
static PyObject *module_score(PyObject *self, PyObject *args) {
int i, size, value, *gene;
PyObject *seq, *data;
/* Parse the input tuple */
if (!PyArg_ParseTuple(args, "O", &data))
return NULL;
seq = PySequence_Fast(data, "expected a sequence");
size = PySequence_Size(seq);
gene = (int*) PyMem_Malloc(size * sizeof(int));
for (i = 0; i < size; i++)
gene[i] = PyInt_AsLong(PySequence_Fast_GET_ITEM(seq, i));
/* Call the external C function*/
value = score(gene, size);
PyMem_Free(gene);
/* Build the output tuple */
PyObject *ret = Py_BuildValue("i", value);
return ret;
}
這工作,但似乎泄漏內存,並在我不能忽視的速度。我通過暫時讓score函數返回0並仍然看到泄漏行爲,確保泄漏發生在顯示的函數中。我曾經想過,對PyMem_Free的調用應該照顧PyMem_Malloc的存儲,但是我目前的猜測是這個函數中的某些東西在每次調用中都得到分配和保留,因爲泄漏行爲與調用此函數的次數成正比。我是不是正確執行數組轉換的序列,或者我可能無效地返回了結尾值?任何幫助表示讚賞。
它認爲,Python有一個內存池,並呼籲'PyMem_Free'不會立即釋放指針。它將內部釋放它,以便Python可以在不重新分配的情況下重用它。但是,我不確定。 – 2014-12-18 23:02:55
你在Linux上嗎?你怎麼確定有泄漏? – 2014-12-18 23:03:59
我在Windows上使用cygwin,這是一個類似Linux的環境。我使用Windows任務管理器和頂部來看到Python進程吃越來越多的內存,然後隨機等待打印,看看只有當這個而不是其他的Python函數被調用時,內存纔會增長。 – hackartist 2014-12-18 23:08:16