Python ctype 'c_char_p' Memory Leak
Python ctypes 'c_char_p' memory leak
我正在开发一个用于密码学的Python库。我想通过用GMP在C++中编写主要类来优化我的库。我编写了C++类,并编写了extern
方法来使用主要的算术运算:加法、减法等。这些方法将结果返回为char*,以避免强制转换问题。我构建了我的库的DLL,并用ctypes在Python包装器中声明了这些方法。我注意到,每次用大数字进行算术运算后,记忆力都呈指数级增长。我一直在寻找C++实现中的问题,但多亏了C++垃圾收集器,才没有问题。我正在寻找一个可能的解决方案,所以我发现我必须实现一个C++方法来释放DLL创建的字符串的内存。所以我写了一个简单的方法:
extern "C" {
__declspec(dllexport) void free_memory(char * n)
{
free(n);
}
...
}
我在Python包装器中实现了这段代码,以释放DLL分配的内存:
import os
import ctypes
DIR_PATH = os.path.dirname(os.path.realpath(__file__))
NUMERIC = ctypes.CDLL(DIR_PATH + "/numeric.dll")
...
NUMERIC.free_memory.argtypes = [ctypes.c_void_p]
NUMERIC.free_memory.restype = None
def void_cast(n):
a = ctypes.cast(n, ctypes.c_char_p)
res = ctypes.c_char_p(a.value)
NUMERIC.free_memory(a)
return res
因此,使用res = ctypes.c_char_p (a.value)
,我创建了一个不再指向a
的新变量。通过这种方式,我使用DLL方法正确地删除了a
,但我仍然存在内存泄漏问题。就好像Python垃圾收集器没有正确释放c_char_p
类型字符串的内存。在以前的实现中,我只使用了Python和gmpy2
库,所以所有的数字都转换为mpz
或mpq
。我使用memory_profiler
软件包测试了内存消耗。我创建了40个类型为投影点的对象,定义在椭圆曲线上,并计算了乘积i*P
,其中i
从1到40。CCD_ 12共使用约70MB。相反,将ctypes与C++中的类一起使用,内存消耗上升到1.5GB。很明显,这是有问题的,尤其是当只有处理算术运算的基类发生变化时。如何在不出现内存泄漏问题的情况下正确释放内存?我举了一个extern
方法的例子来计算算术运算,但我已经检查过问题只在于通过free_memory
函数正确释放内存,并重新分配字符串,以便Python的垃圾收集器在需要时释放字符串。
extern "C" {
__declspec(dllexport) const char* rat_add(const char * n, const char * m)
{
return (RationalNum(n) + RationalNum(m)).getValue();
}
}
提前谢谢,祝你今天愉快。
PS:很明显,在C++中,我正确地实现了析构函数方法,以释放创建的mpz_t
和mpq_t
对象的空间。
问题出在这一行:
res = ctypes.c_char_p(a.value)
这将创建a.value
的副本,并将res
设置为指向该副本的c_char_p
。然而,Python不为ctypes
指针做内存管理,因此副本会被泄露!
如果用替换上述线路,则应修复泄漏
res = bytes(memoryview(a.value))
这也会创建一个副本,但res
将是一个真正的Python对象。
- Python ctype 'c_char_p' Memory Leak
- 模式"allocate memory or use existing data"
- Win32 API - HWND "{unused = ???} Unable to read memory"错误
- "in-situ without memory allocation" 字符串的愚蠢实现意味着什么?
- C++ "Using Uninitialized Memory.. (variable name) "
- "Memory Fragmentation"这仍然是一个问题?
- 封送指向结构异常"cannot Read or Write protected memory"的指针数组的指针数组
- 向量数组"Cannot access memory at address"
- 什么是"Reading unbounded stream from standard input (Memory Management)"的例子
- 我在 C++ "out_of_range at memory location"有问题
- QML QQmlPropertyList - 包含的对象生存期和'memory rules'
- Java 本机访问代码错误:"Invalid memory access"
- 编写"anti-lack of memory"异常安全代码
- IDXGISwapChain::Present Memory Leak
- Memory Leak Strtok & ATOF
- 视觉奇怪"Memory Leak Detection"错误C++
- Visual C++ 2013 Memory Leak Wostringstream, Imbue & locale facets
- POSIX 线程 - 使用条件变量 MEMORY LEAK 同步分离的线程
- C++ Boost::Thread & Boost::ASIO Memory leak
- istringstream() (possibly) memory leak