リストのサイズが事前にわかっている場合は、通常、適切なサイズでリストを作成して を使用する方が高速PyList_SetItem()
です。
あなたのコードは単に間違っており、初期化されていませんtrio_tmp
。
これを試して:
PyObject * bugmaybe(PyObject *self, PyObject *args)
{
PyObject * trio=PyList_New(3);
PyObject * otmp = PyFloat_FromDouble(1.2);
PyList_SetItem(trio,0,otmp);
otmp = PyFloat_FromDouble(2.3);
PyList_SetItem(trio,1,otmp);
PyList_Append(trio,2, PyList_New(0));
return trio;
}
本当に を使用したい場合PyList_Append
、コードはほとんどtrio_tmp
問題なく、最後に の初期化と余分な Py_INCREF が欠けているだけです。
PyObject * bugmaybe(PyObject *self, PyObject *args)
{
PyObject * trio=PyList_New(0);
// trio has refcount 1
PyObject * trio_tmp = PyList_New(0);
// trio_tmp has recount 1
PyObject * otmp = PyFloat_FromDouble(1.2);
// otmp has recount 1
PyList_Append(trio_tmp,otmp);
// Append does not steal a reference, so otmp refcoun = 2
Py_DECREF(otmp);
// otmp refcount = 1, but stored in the list so the pointer var
// can be reused
otmp = PyFloat_FromDouble(2.3);
PyList_Append(trio_tmp,otmp);
Py_DECREF(otmp);
// as above
PyList_Append(trio,trio_tmp);
// decrement refcount for trio_tmp, as it has recount 2 now.
Py_DECREF(trio_tmp);
return trio;
}
上記のコードは次と同等です。
trio = []
trio_tmp = []
otmp = 1.2
trio_tmp.append(otmp)
otmp = 2.3
trio_tmp.append(otmp)
trio.append(trio_tmp)
それが役に立てば幸い。主なヒントはドキュメントにあります。「参照を盗む」と表示されている場合、関数は基本的に所有権を取得します。「新しい参照」と表示されている場合は、INCREF を実行します。何も言われていない場合は、おそらく INCREF と DECREF のペアを実行します必要に応じて。