Impossibile trovare la causa della perdita di memoria in questo codice.Perdita di memoria XS in questo codice?
Fondamentalmente voglio scrivere un wrapper XS per una funzione C che restituisce un array bidimensionale.
C-funzione:
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 involucro:
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;
}
Un "array di matrice" viene restituito da XS.
test in script Perl:
for(1..100)
{
my ($status, $arrayref) = returnArray();
undef $status;
$arrayref = [];
system('pause');
}
Ogni volta che la funzione viene chiamata returnArray()
, la dimensione Commit del processo Perl è in aumento. Ma mi aspetto che la variabile $arrayref
debba essere raccolta ogni volta e l'utilizzo della memoria non dovrebbe aumentare.
Spero di liberare tutta la memoria allocata in XS. Ma c'è ancora una perdita di memoria. Cosa c'è di sbagliato in questo codice XS per perdita di memoria?
Non si rilascia alcuno degli scalari creati utilizzando 'newSVnv'. Invece di copiare tutti questi SV usando 'av_make', dovresti assegnare crea un popolamento dell'array tu stesso. 'newAV' +' av_extend' + 'av_fetch' – ikegami
Ma che dire di questo codice? '/ ** libera la memoria allocata per l'array SV temporaneo **/ per (j = 0; j
InnovWelt
Non chiamare mai 'sv_free'. Usa 'SvREFCNT_dec'. – ikegami