假设我写了一些C/C++代码,它会分配一些内存,并返回一个指向它的指针。
#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中使用以下脚本进行了测试。
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
以下是输出结果:
报告1:
==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
报告2:
==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
Python 3.3.2
中,这两个报告都显示泄漏了2048字节,但是在Python 2.7.5
中,这两个报告都没有泄漏。在Linux 3.11.4 x86_64
上测试,使用的编译器是gcc 4.8.1 20130725
。 - starrify