2016-05-05 11 views
2

C++ dllのPythonラッパーでメモリリークを修正しようとしています。 問題はPythonで作成されているヘルパーオブジェクトにバイトのバッファを割り当てるときです:SWIG typemapからのメモリ割り当て解除

struct ByteBuffer 
{ 
    int length; 
    uint8_t * dataBuf;  
}; 

は、私はPythonの配列としてdataBufを提供したいので、私が思いついたタイプマップ(と作品)

%module(directors="1") mymodule 

%typemap(in) uint8_t * (uint8_t *temp){ 
    int length = PySequence_Length($input); 
    temp = new uint8_t[length]; // memory allocated here. How to free? 
    for(int i=0; i<length; i++) { 
     PyObject *o = PySequence_GetItem($input,i); 
     if (PyNumber_Check(o)) { 
      temp[i] = (uint8_t) PyLong_AsLong(o); 
      //cout << (int)temp[i] << endl; 
     } else { 
      PyErr_SetString(PyExc_ValueError,"Sequence elements must be uint8_t");  
      return NULL; 
     } 
    } 
    $1 = temp; 
} 

問題はタイプマップは、新しいCアレイに毎回メモリを割り当て、このメモリは、DLL内に解放されないことである。ということです。つまり、dllは、ユーザーがByteBufferのdataBufのメモリを管理することを期待しています。例えば、Pythonで順次10000ようなオブジェクトを作成し、それらを削除し、それはメモリ使用量が着実に(漏れ)を上昇すると:

for i in range(10000): 
    byteBuffer = mymodule.ByteBuffer() 
    byteBuffer.length = 10000 
    byteBuffer.dataBuf = [0]*10000 
    # ... use byteBuffer 
    del byteBuffer 

は、Pythonから割り当てdataBufを削除するが方法はありますか?お待ちいただいてありがとうございます!

編集:私はそれを短く保つために作業コード全体を投稿しません。必要なら、私はそれをやるでしょう。さらに、私はPython 3.5 x64とSWIG ver 3.0.7を使用しています

+0

あなたの例は非常に完全な例であるため、1つにすることもできます。 ℅inlineを使用して.Iファイルに構造体定義を追加することができます。 – Flexo

答えて

0

これは私が思ったよりはるかに単純でした。私はちょうど.iファイルに追加しました。

%typemap(freearg) uint8_t * { 
    //cout << "Freeing uint8_t*!!! " << endl; 
    if ($1) delete[]($1); 
} 

と思われます。 編集:削除で自由に切り替えました[]

+0

あなたは 'new []'で割り当てたので、未定義の振る舞いを避けるために 'delete []'で解放するべきです。 nullのチェックは余分です。 – Flexo

+0

@Flexoは、削除[]でも動作するようです。なぜfree()が未定義の動作を生成するのかは分かりません。 –

+0

"うまくいく"かどうかは関係ありませんが、間違っています。 http://stackoverflow.com/questions/1612031/is-there-any-danger-in-calling-free-or-delete-instead-of-delete – Flexo

関連する問題