このコードでメモリリークがどこで発生しているのかを見つけることができません。XSこのコードのメモリリーク?
基本的には、2次元配列を返す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プロセスのコミットサイズが増加しています。 しかし、毎回$arrayref
変数をガベージコレクションする必要があり、メモリ使用量を増やすべきではないと思います。
私は、XSで割り当てられたすべてのメモリを解放したいと思います。しかし、まだメモリリークがあります。 メモリリークのこのXSコードで何が問題になっていますか?
あなたは 'newSVnv'を使って作成されたスカラの割り当てを解除しません。 'av_make'を使ってこれらのSVをすべてコピーするのではなく、あなた自身が配列を作成するようにcreateを割り当てる必要があります。 'newAV' +' av_extend' + 'av_fetch' – ikegami
このコードはどうですか? '/ **一時SV配列に割り当てられたメモリを解放する**/ (j = 0; j
InnovWelt
決して 'sv_free'を呼び出さないでください。 'SvREFCNT_dec'を使用してください。 – ikegami