无法在此代码中找到内存泄漏的位置。
基本上我想为C函数编写一个XS包装器,它返回一个二维数组。
C-功能:
int CW_returnArray(double** arrayDouble, int* count)
{
int number = 10;
int index, index1;
for(index = 0; index < number; index++)
{
for(index1 = 0; index1 < 10000; index1++)
{
arrayDouble[index][index1] = 12.51;
}
count[index] = 10000;
}
return number;
}
array -> output param to hold the two dimensional array
count -> output param to hold the number of element in each 1D array
XS包装器:
void
returnArray()
PPCODE:
{
/** variable declaration **/
double** array;
int i = 0, j=0, status;
int* count;
int totalArrays;
SV** SVArrays; // to hold the references of 1D arrays
SV** SVtempArray; // temporary array to hold the elements of 1D array
/** allocate memory for C-type variables **/
New(0, array, 10, double*);
for(i = 0; i<10;i++)
{
New(0, array[i], 10000, double);
}
New(0, count, 10, int);
/** call C function **/
status = CW_returnArray(array, count);
/** check the status and retrieve the array to store it in stack **/
if(status > 0)
{
totalArrays = status;
New(0, SVArrays, totalArrays, SV*);
for(i = 0; i<totalArrays; i++)
{
/** allocate memory for temporary SV array **/
New(0, SVtempArray, count[i], SV*);
for(j = 0; j<count[i]; j++)
{
SVtempArray[j] = newSVnv(array[i][j]);
}
/** Make an array (AV) out of temporary SV array and store the reference in SVArrays **/
SVArrays[i] = newRV_noinc((SV*) av_make(count[i], SVtempArray));
/** free the memory allocated for temp SV array **/
for(j = 0; j<count[i]; j++)
{
sv_free(SVtempArray[j]);
}
Safefree(SVtempArray); SVtempArray = NULL;
}
}
else
{
totalArrays = 0;
}
/** push the return values to stack **/
EXTEND(SP, 2);
PUSHs(sv_2mortal(newSViv(status)));
PUSHs(sv_2mortal(newRV_noinc((SV*) av_make(totalArrays, SVArrays))));
/** clean up allocated memory for SV "array of array" , if needed **/
if(totalArrays > 0)
{
Safefree(SVArrays); SVArrays = NULL;
}
/** clean up allocated memory for C-type variables **/
for(i = 0; i<10;i++)
{
Safefree(array[i]);
}
Safefree(array); array = NULL;
Safefree(count); count = NULL;
}
从XS返回“数组数组”。
在Perl脚本中进行测试:
for(1..100)
{
my ($status, $arrayref) = returnArray();
undef $status;
$arrayref = [];
system('pause');
}
每次调用函数returnArray()
时,Perl进程的Commit大小都会增加。
但我希望每次都应该对$arrayref
变量进行垃圾收集,并且内存使用量不应该增加。
我希望,我释放了XS中所有已分配的内存。但仍有内存泄漏。 这个内存泄漏的XS代码有什么问题?
答案 0 :(得分:7)
好吧,&#34;模式创建一个模板数组,做av_make()
,然后释放模板&#34;不是很好 - 只需使用newAV()
创建数组,av_extend()
将其设置为正确的大小,然后为每个元素执行av_store(newSVnv(...))
,您就会好得多。这样可以完全避免中间SVtempArray
分配。
但是,这不是你问的问题。我认为您的问题是Safefree(SVArrays)
没有首先sv_free()
每个元素。由于av_make()
重复源数组的内容,因此AFAICT会泄漏由
SVArrays[i] = newRV_noinc((SV*) av_make(count[i], SVtempArray));
您需要在sv_free()
之前迭代SVArrays并在每个元素上调用Safefree(SVArrays)
。