2012-09-29 6 views
5

का उपयोग कर रहा डेल्फी कोडमेमोरी मुक्त कैसे जब बाहर का स्मृति अपवाद डेल्फी में होता है SetLength

var 
    a: array of array of array of integer; 
begin 
    try 
    SetLength(a, 100000, 100000, 10000); // out of memory here 
    doStuffs(a); 
    except 
    a = nil; // try to free the memory 
    end; 
end; 

का एक टुकड़ा ऊपर कोड स्मृति के बहुत सारे आवंटित करने के लिए और out-of-memory पकड़ा हो जाएगा की कोशिश करता है। a=nil निष्पादित किया जाएगा, लेकिन स्मृति मुक्त नहीं है।

क्या मेमोरी अपवाद के मामले में स्मृति को मुक्त करने का कोई तरीका है?

मैंने SetLength(a, 0, 0, 0) और Finalize(a) की कोशिश की, और दोनों काम नहीं करेंगे।

+0

जब आप अपवाद हैंडलर में हों, तो क्या '' में एक गैर-शून्य मान भी है? यदि नहीं, तो आप शायद ही इसे मुक्त करने में सक्षम होने की उम्मीद कर सकते हैं। इसके अलावा, यह वैसे भी समारोह के अंत में मुक्त हो जाएगा। क्या आपने पुष्टि की है कि 'SetLength'' a' चर सेट करता है जब यह सभी अनुरोधित मेमोरी आवंटित नहीं कर सकता है? –

+0

@Rob No, अपवाद हैंडलर में 'a'' nil' है। –

+0

हां, एक = शून्य जब कोड अपवाद ब्लॉक में कदम उठाता है। पीएस: मैंने फास्टएमएम को मेमोरी मैनेजर के रूप में इस्तेमाल किया। –

उत्तर

7

सामान्य रूप से, स्मृति त्रुटि से पुनर्प्राप्त करना संभव नहीं है। उस बिंदु पर ढेर सबसे अधिक भ्रष्ट है। उचित प्रतिक्रिया प्रक्रिया को समाप्त करना है।

इस विशिष्ट मामले में, आवंटन DynArraySetLengthSystem इकाई में किया जाता है। यह बार-बार आवंटन करता है। केवल DynArraySetLength का अंतिम कार्य उपरोक्त आपके कोड में वापसी मूल्य, a है, वास्तव में असाइन किया गया है। और यदि DynArraySetLength में त्रुटियां होती हैं तो रनटाइम को व्यवस्थित करने का कोई प्रयास नहीं होता है। जिसका अर्थ है कि विफलता के मामले में आवंटित कोई भी स्मृति लीक हो जाती है और उसे पुनर्प्राप्त नहीं किया जा सकता है। इसे मुक्त करने के लिए आपके पास इसका संदर्भ देने का कोई तरीका नहीं है।

आपको लगता है कि DynArraySetLength को साफ करने के लिए और कुछ करना चाहिए। हालांकि, यह दृष्टिकोण न्यायसंगत है। चूंकि स्मृति स्थितियों में से हमेशा भ्रष्ट ढेर में परिणामस्वरूप, साफ-सफाई करने का प्रयास केवल पीड़ा को बढ़ाएगा। एक बार ढेर मरने के बाद, स्मृति को हटाने की कोशिश करने में कोई बात नहीं है।

+1

प्राकृतिक अनुवर्ती प्रश्न यह है कि 'क्या कोई' trySetLength' प्रक्रिया है? ' –

+1

@AndreasRejbrand कोई नहीं है। –

+0

क्या आप निश्चित हैं? ऐसा लगता है कि यह स्मृति प्रबंधक आंतरिक पर निर्भर करता है कि ढेर दूषित है या नहीं। – kludg

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