提问人:Alan Yu 提问时间:10/10/2023 最后编辑:Alan Yu 更新时间:10/11/2023 访问量:48
使用 python ctypes 进行 2D 数组乘法后无法释放内存
Fail to release the memory after 2D array multiplication with python ctypes
问:
我尝试使用 python ctypes 模块调用 DLL 中的函数。这些函数成功执行 2D 数组乘法,并由 C 创建。以下源代码将由 Visual Studio 2017 打包到“matrixDLL.dll”中。
C 代码
//arrayMulti.cpp - will be packaged into "matrixDLL.dll" by Visual Studio 2017.
#include "pch.h"
#include <stdio.h>
#include <stdlib.h>
extern "C" {//prtA: array A, ay: number of rows for A, ax: number of columns for A, prtB: array B
__declspec(dllexport) double** D2_Dot(double* prtA, int ay, int ax, double* prtB, int by, int bx)
{
//allocate memory for 2D array A and assign values
double** A = (double**)malloc(sizeof(double*)*ay);
for (int i = 0; i < ay; i++)
A[i] = (double*)malloc(sizeof(double)*ax);
for (int i1 = 0; i1 < ay; i1++)
for (int i2 = 0; i2 < ax; i2++)
A[i1][i2] = *(prtA + i1 * ax + i2);
//allocate memory for 2D array B and assign values
double** B = (double**)malloc(sizeof(double*)*by);
for (int j = 0; j < by; j++)
B[j] = (double*)malloc(sizeof(double)*bx);
for (int j1 = 0; j1 < by; j1++)
for (int j2 = 0; j2 < bx; j2++)
B[j1][j2] = *(prtB + j1 * bx + j2);
//allocate memory for the resulting array C
double** C = (double**)malloc(sizeof(double*)*ay);
for (int k = 0; k < ay; k++)
C[k] = (double*)malloc(sizeof(double)*bx);
if (ax != by) {
printf("Dimension Error!!\n");
}
else {
//find the values of the resulting array C
for (int i = 0; i < ay; i++)
for (int j = 0; j < bx; j++)
for (int k = 0; k < by; k++)
C[i][j] += A[i][k] * B[k][j];
return C;
}
}
__declspec(dllexport) void free_memDyn(double** ptr, int ny, int nx)
{
for (int f = 0; f < ny; f++)
free(ptr[f]);
free(ptr);
}
}
然后我使用 python ctypes 模块从上面的 DLL 调用函数。请注意,我应用了 POINTER() 而不是指针,这是因为 pointer() 函数创建了一个新的指针实例,指向一个对象。相比之下,POINTER() 是一个工厂函数,用于创建并返回新的 ctypes 指针类型。
matrix.D2_Dot.restype = POINTER(POINTER(c_double * bCol) * aRow)
Python 代码
from ctypes import *
matrix = cdll.LoadLibrary('matrixDLL.dll')
A = [[1.0,2.0],[3.0,4.0]]
B = [[0.0,1.0],[2.0,3.0]]
aRow = len(A)
aCol = len(A[0])
ptrA = (c_double*aCol*aRow)()
for i in range(aRow):
for j in range(aCol):
ptrA[i][j] = A[i][j]
bRow = len(B)
bCol = len(B[0])
ptrB = (c_double*bCol*bRow)()
for i in range(bRow):
for j in range(bCol):
ptrB[i][j] = B[i][j]
matrix.D2_Dot.restype = POINTER(POINTER(c_double * bCol) * aRow)
dotRes = matrix.D2_Dot(ptrA,aRow,aCol,ptrB,bRow,bCol)
arrList = [[0.]*bCol for _ in range(aRow)]
for i in range(aRow):
for j in range(bCol):
arrList[i][j] = dotRes.contents[i][0][j]
#Return the correct result.
print('arrList[0][0]: ',arrList[0][0])#4.0
print('arrList[0][0]: ',arrList[0][1])#7.0
print('arrList[0][0]: ',arrList[1][0])#8.0
print('arrList[1][1]: ',arrList[1][1])#15.0
#Program crashes at the following lines.
#matrix.free_memDyn(ptrA, aRow, aCol)
#matrix.free_memDyn(ptrB, bRow, bCol)
#matrix.free_memDyn(ptrA, aRow, aCol)
以下几行显示了正确的结果。
但是程序在这一行开始崩溃:
matrix.free_memDyn(ptrA, aRow, aCol);
错误消息类似于“内存崩溃”。由于操作系统和程序环境不同,我没有列出详细信息。
如果 free() 函数失败,则会导致内存泄漏。如何解决此问题?
答: 暂无答案
评论
ptrA
并传入您的函数。没有理由将它们分配和复制到并且这些分配无论如何都不会被传递出来释放......只有。ptrB
A
B
C
numpy