2013-08-15 9 views
8

इस कोड में मेमोरी लीक कहां हो रहा है यह जानने में असमर्थ।एक्सएस मेमोरी रिसाव?

मूल रूप से मैं एक सी-फ़ंक्शन के लिए एक एक्सएस रैपर लिखना चाहता हूं जो एक द्वि-आयामी सरणी देता है।

सी समारोह:

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 से दिया जाता है। पर्ल स्क्रिप्ट में

परीक्षण:

for(1..100) 
{ 
    my ($status, $arrayref) = returnArray(); 
    undef $status; 
    $arrayref = []; 
    system('pause'); 
} 

हर बार समारोह returnArray() कहा जाता है, पर्ल की प्रक्रिया के लिए प्रतिबद्ध आकार बढ़ रही है। लेकिन मुझे उम्मीद है कि $arrayref परिवर्तक हर बार कचरा एकत्र किया जाना चाहिए और मेमोरी उपयोग में वृद्धि नहीं होनी चाहिए।

मुझे आशा है कि, मैं एक्सएस में सभी आवंटित स्मृति को मुक्त कर रहा हूं। लेकिन अभी भी एक स्मृति रिसाव है। मेमोरी लीक के लिए इस एक्सएस कोड में क्या गलत है?

+0

आप 'newSVnv' का उपयोग करके बनाए गए किसी भी स्केलर को अस्वीकार नहीं करते हैं। 'Av_make' का उपयोग करके उन सभी एसवी को कॉपी करने के बजाय, आपको स्वयं को सरणी बनाने के लिए असाइन करना चाहिए। 'newAV' +' av_extend' + 'av_fetch' – ikegami

+0

लेकिन इस कोड के बारे में क्या? '/ ** temp एसवी सरणी **/ के लिए आवंटित स्मृति मुक्त करें (जे = 0; जे <गिनती [i]; j ++) { sv_free (SVtempArray [j]); } '। 'Sv_free()' कॉल 'newSVnv() 'का उपयोग करके बनाए गए एसवी को रद्द नहीं करेगा? – InnovWelt

+0

कभी भी 'sv_free' को कॉल न करें। 'SvREFCNT_dec' का प्रयोग करें। – ikegami

उत्तर

7

ठीक है, की तर्ज "टेम्पलेट सरणी बनाने के लिए, कर av_make(), तो टेम्पलेट मुक्त" बहुत अच्छा नहीं है - आप बहुत बस, newAV() के साथ अपने सरणी बनाने av_extend() सही आकार के लिए यह ing द्वारा बेहतर होगा , और फिर प्रत्येक तत्व के लिए av_store(newSVnv(...)) कर रहे हैं। इससे आप मध्यवर्ती SVtempArray आवंटन से पूरी तरह से बच सकते हैं।

हालांकि, यह नहीं है कि आपने जो पूछा है। मुझे लगता है कि आपकी समस्या यह है कि आप Safefree(SVArrays) बिना किसी तत्व के sv_free() के बिना। चूंकि av_make()डुप्लिकेट स्रोत सरणी की सामग्री, AFAICT आप द्वारा

SVArrays[i] = newRV_noinc((SV*) av_make(count[i], SVtempArray)); 

बनाया संदर्भ लीक कर रहे हैं आप SVArrays से अधिक पुनरावृति और आप Safefree(SVArrays) से पहले प्रत्येक तत्व पर sv_free() कॉल करने के लिए की आवश्यकता होगी।

+0

इस कोड के साथ समस्या को इंगित करने के लिए धन्यवाद। 'sv_free()' का उपयोग एक ही स्थान पर किया गया था ('(j = 0; j InnovWelt

संबंधित मुद्दे