2016-11-20 6 views
3

PyDict内の既存のフィールドに新しい値が設定されている場合(C拡張内)のメモリ管理/参照カウントがどのように機能するのか疑問に思っています。例えばPyDict_SetItemStringを使用した参照カウント

、辞書は次のように作成し、移入され前提としています

myPyDict = PyDict_New(); 
tempPyObj = PyString_FromString("Original Value"); 
PyDict_SetItemString(myPyDict,"fieldname",tempPyObj); 
Py_DECREF(tempPyObj); 

メモリと参照カウントの観点から、その後の

tempPyObj = PyString_FromString("New Value"); 
PyDict_SetItemString(myPyDict,"fieldname",tempPyObj); 
Py_DECREF(tempPyObj); 

がありますされたときに何が起こるかは、元の値の参照カウントが自動的にデクリメントされます(メモリは自動的に解放されます)。

PyList_SetItemためのドキュメントは、特にリストに何が起こるかを言及:This function “steals” a reference to item and discards a reference to an item already in the list at the affected position.

しかし、どちらもPyDic_SetItemPyDict_SetItemStringは交換が辞書のためにどのように処理されるかと言います。

答えて

2

古い値のrefカウントは、PyList_SetItemの機能によって自動的に減分されます。 あなた自身で古い値を減らすべきではありません。

詳細を知りたい場合は、具体的にはObjects/dictobject.cファイルのCPythonソースコードをご覧ください。

1)PyDict_SetItemString()

https://github.com/python/cpython/blob/c8e7c5a/Objects/dictobject.c#L3250-L3262

それは薄いラッパー周りPyDict_SetItem()

2)PyDict_SetItem()

https://github.com/python/cpython/blob/c8e7c5a/Objects/dictobject.c#L1537-L1565

です

まだかなり単純です.Dict内の値の挿入/置換に関連するすべての重労働は、実際にはinsertdict()によって行われていることは明らかです。

3)insertdict()

https://github.com/python/cpython/blob/c8e7c5a/Objects/dictobject.c#L1097-L1186

私たちに答えを与える関数です。この関数では、重要なコード、特に呼び出しを見つけることができます。

Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */ 

古い値のrefカウントをデクリメントします。

関連する問題