私はUbuntuでプログラミングしています(Python 2.7.3
)。Python CFFIメモリ管理の問題
私はCFFIを使用して、PythonリストにいくつかのCコードからの値を移入しています。
このリストはかなり大きく、印刷すると約71000文字です。
Cコードでは多くのライブラリが使用されています。したがって、次のコードは何が起きているのかをより深く理解するためのものです。
datas_list = []
for i in range(0, x):
c_pDataStructure = ffi.new("c_DataStructure[]", 1) // Create a pointer to the data structure
c.SomeCFunction(c_pDataStructure) // Populate the data structure
datas_list.append(c.GetSomeInfo(c_pDataStructure)) // Get some info from the data structure
c.FreeDataStructure(c_pDataStructure) // Release dynamically allocated memory
プログラムは、右の前に、コマンドラインから起動するときWingware IDEを使用しても動作しますが、glibcのエラー(*** glibc detected *** python: free(): invalid next size (fast): 0x0000000003b0b080 ***
)で終了します。WIMのanswerを読んだ後
c_pDataStructure = ffi.new("c_Datastructure[]", 1)
両方の場合、私がチェックIDEとコマンドラインは同じインタプリタを使用してコードを実行していました - (/usr/bin/python
)です。
EDIT(valgrindのレポート):
==5089== Process terminating with default action of signal 11 (SIGSEGV)
==5089== General Protection Fault
==5089== at 0x54FBB0: PyObject_Malloc (in /usr/bin/python2.7)
==5089== by 0x10B30625: allocate_owning_object (_cffi_backend.c:2972)
==5089== by 0x10B40EE8: allocate_with_allocator.constprop.84 (_cffi_backend.c:3032)
==5089== by 0x10B41010: direct_newp (_cffi_backend.c:3153)
==5089== by 0x10B4138C: b_newp (_cffi_backend.c:3177)
==5089== by 0x4F95A4: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==5089== by 0x5008C1: PyEval_EvalCodeEx (in /usr/bin/python2.7)
==5089== by 0x4F9AB7: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==5089== by 0x4F9D01: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==5089== by 0x4F9D01: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==5089== by 0x4F9D01: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==5089== by 0x4F9D01: PyEval_EvalFrameEx (in /usr/bin/python2.7)
EDIT:
ここでは、Cデータ構造に関するいくつかの詳細です。これは、それがどのように見えるかです:
typedef struct _STRUCT3{
some int, char*
}STRUCT3, *PSTRUCT3;
typedef struct _STRUCT2{
some int
PSTRUCT3 pStruct3;
}STRUCT3, *PSTRUCT3;
typedef struct _STRUCT1{
some int, char*
PSTRUCT2 pStruct2;
}STRUCT1, *PSTRUCT1;
私は割り当て/割り当て解除フルC構造にはほとんどCプログラムを作り、valgrind
は、任意のメモリリークを見つけることができませんでした。
質問:
- 上記
valgrind
レポートは正確に何を意味するのでしょうか? - IDEからのプログラムとコマンドラインからのプログラムの実行の違いは何ですか?
注:IDEはPythonの引数-u (unbuffered)
を使用してプログラムを実行しますが、コマンドラインに追加することで違いはありません。 - 私自身で構造体の割り当てを解除すると、Pythonのガベージコレクタは動作しますか?代わりに
ffi.gc(c_pDataStructure, c.FreeDataStructure)
を使用する必要がありますか?
'FreeDataStructure(p)'はポインタ '' p''自体を解放するべきではなく、内部に動的に割り当てられたものだけを解放すべきです。私はこれが当てはまると思いますか? –
はい、FreeDataStructureは、ポピュレート関数が動的に割り当てたすべてを解放します – DRz
オプションのメンバーを持つデータ構造が33回目に割り当てられた後、プログラムがクラッシュします。したがって、私はオプションの値が適切に解放されないことを疑う。以前に使用されたメモリアドレスを上書きする前に、Python(またはCFFIまたはC?)が "32メモリアドレス範囲"に入っていませんか?次に、Wingwareが64ビットPythonでコマンドラインを実行し、32ビットPythonでコマンドラインを実行すると、後者がglibcエラーで終了する理由を説明することができます... – DRz