In diesem Code kann der Speicherleck nicht gefunden werden.XS Speicherleck in diesem Code?
Grundsätzlich möchte ich einen XS-Wrapper für eine C-Funktion schreiben, die ein zweidimensionales Array zurückgibt.
C-Funktion:
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 wrapper:
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;
}
Ein "Array von Array" von XS zurückgegeben.
Tests in Perl-Skript:
for(1..100)
{
my ($status, $arrayref) = returnArray();
undef $status;
$arrayref = [];
system('pause');
}
Jedes Mal, wenn die Funktion returnArray()
aufgerufen wird, wird die Commit Größe von Perl-Prozess zu erhöhen. Aber ich würde erwarten, dass die $arrayref
Variable Müll jedes Mal gesammelt werden sollte und die Speicherbelegung sollte nicht erhöht werden.
Ich hoffe, ich befreie den gesamten zugewiesenen Speicher in XS. Aber immer noch gibt es ein Speicherleck. Was ist mit diesem XS-Code für Speicherverlust falsch?
Sie können keine der Skalare, die mit 'newSVnv' erstellt wurden, deallozieren. Anstatt alle diese SVs mit 'av_make' zu kopieren, sollten Sie create erstellen und das Array selbst auffüllen. 'newAV' +' av_extend' + 'av_fetch' – ikegami
Aber was ist mit diesem Code? '/ ** gebe den Speicher frei, der für das temp SV-Array zugewiesen wurde **/ für (j = 0; j
InnovWelt
Niemals 'sv_free' aufrufen. Verwende 'SvREFCNT_dec'. – ikegami