メモリを割り当ててポインタを返すC/C++コードを考えてみましょう。Python:ctypesを使ったガベージコレクタの動作
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
void Allocate(void **p) {
int N=2048;
*p=malloc(N);
}
#ifdef __cplusplus
}
#endif
明らかにそのブロックを解放するのは私の責任だと思っています。 これを共有ライブラリにコンパイルし、ctypesでPythonから呼び出すが、明示的にそのメモリを解放しないとします。
import ctypes
from ctypes import cdll, Structure, byref
external_lib = cdll.LoadLibrary('libtest.so.1.0')
ptr=ctypes.c_void_p(0)
external_lib.Allocate(ctypes.byref(ptr))
私はvalgrindのと、このスクリプトを実行する場合、私は「-O3」フラグなしTEST.CPPをコンパイルする場合は、私が2048バイトのメモリリークを取得します。しかし、 '-O3'フラグを付けてコンパイルすると、メモリリークは発生しません。
これは実際問題ではありません。割り当てたメモリを明示的に解放するように常に注意します。しかし、私はこの行動がどこから来るのか興味があります。
これをlinuxの以下のスクリプトでテストしました。
==27875== LEAK SUMMARY:
==27875== definitely lost: 2,048 bytes in 1 blocks
==27875== indirectly lost: 0 bytes in 0 blocks
==27875== possibly lost: 295,735 bytes in 1,194 blocks
==27875== still reachable: 744,633 bytes in 5,025 blocks
==27875== suppressed: 0 bytes in 0 blocks
報::次の出力
報と
g++ -Wall -c -fPIC -fno-common test.cpp -o libtest1.o
g++ -shared -Wl,-soname,libtest1.so.1 -o libtest1.so.1.0 libtest1.o
g++ -O3 -Wall -c -fPIC -fno-common test.cpp -o libtest2.o
g++ -shared -Wl,-soname,libtest2.so.1 -o libtest2.so.1.0 libtest2.o
valgrind python test1.py &> report1
valgrind python test2.py &> report2
==27878== LEAK SUMMARY:
==27878== definitely lost: 0 bytes in 0 blocks
==27878== indirectly lost: 0 bytes in 0 blocks
==27878== possibly lost: 295,735 bytes in 1,194 blocks
==27878== still reachable: 746,681 bytes in 5,026 blocks
==27878== suppressed: 0 bytes in 0 blocks
:
ここでは、両方の到達可能と到達不能ブロックを示すvalgrindのからの結果の抜粋です。 'Python 3.3.2'では、2つのレポートの両方で2048バイトのリークが発生しますが、Python 2.7.5ではどちらのレポートでもリークはありません。 'Linux 3.11.4 x86_64'で' gcc 4.8.1 20130725'とテストされました – starrify