2013-02-19 60 views
14

अपने आवेदन में मैं निम्नलिखित रिकॉर्ड है:क्या मुझे डेल्फी में रिकॉर्ड्स की सरणी को अंतिम रूप देने की आवश्यकता है?

TTransaction = record 
    Alias: string 
    Description: string 
    Creation: TDateTime 
    Count: Integer 
end; 

और मैं इस सरणी में इस रिकॉर्ड उपयोग कर रहा हूँ:

Transactions = array of TTransaction; 

मैं सरणी रनटाइम के दौरान लोड रखने कर रहा हूँ, लेकिन एक पर दिया समय मुझे सभी डेटा साफ़ करने और कुछ नया जोड़ने की जरूरत है।

SetLength(Transactions, 0); ? 

या मैं कुछ को अंतिम रूप देने की जरूरत है:

यह काफी बस का उपयोग करने के है?

उत्तर

15

वहाँ एक गतिशील सरणी के साथ स्मृति सहयोगियों पुनःआवंटन के लिए तीन तरीके, a हैं:

SetLength(a, 0); 
Finalize(a); 
a := nil; 

यह आपके ऊपर उपयोग करने के लिए है।

documentation, एक ही कहते हैं यद्यपि में एक से थोड़ा दौर फैशन के बारे में:

एक गतिशील सरणी पुनःआवंटन करने के लिए, एक चर सरणी का संदर्भ या अंतिम रूप देने के चर पारित करने के लिए नहीं के बराबर आवंटित; इनमें से कोई भी तरीका सरणी का निपटान करता है, बशर्ते इसमें कोई अन्य संदर्भ न हो। गतिशील सरणी स्वचालित रूप से रिलीज़ हो जाती हैं जब उनकी संदर्भ-गणना शून्य पर गिर जाती है।लंबाई 0 के गतिशील सरणी मान शून्य है।

यह आपके रिकॉर्ड प्रकार के स्वामित्व वाले किसी भी नेस्टेड प्रबंधित प्रकारों जैसे तारों, गतिशील आर्य आदि सहित सरणी से जुड़ी सभी मेमोरी को रिलीज़ करेगा।

यदि आपको भविष्य के उपयोग के लिए सरणी का आकार बदलने की आवश्यकता है, और नया डेटा उपलब्ध है, तो बस SetLength का उपयोग करके आकार बदलें, और शेष तत्वों को उचित रूप से प्रारंभ करें।

+1

क्या 'अंतिमकरण' वास्तव में 'ए' के मान को बदलता है, हालांकि? मैं हमेशा इस धारणा के तहत रहा हूं कि यह नहीं है - यह 'ए' में संग्रहीत गतिशील सरणी के मूल पते को छोड़कर स्मृति को मुक्त करता है, बाद में किसी भी कॉल की प्रत्याशा में' फ्री 'या' प्रारंभ करें '। –

+1

@Rob एक गतिशील सरणी के लिए, ये तीन विकल्प समकक्ष हैं। प्रबंधित प्रकार के लिए, अंतिम रूप से संदर्भ को सेट करना होगा। इसमें कोई विकल्प नहीं है। एक गतिशील सरणी प्रकार के स्थानीय चर पर विचार करें। –

+0

@ डेविड हेफरनन उन मामलों में जहां सरणी की उच्चतम सीमा 10 है, जो उपयोग करने के लिए बेहतर है: 1- नील पर सेट करें और सभी को फिर से बनाएं। 2 - प्रयुक्त इंडेक्स को अगले मानों से संबद्ध करें ?? – EProgrammerNotFound

0

SetLength (transactions,0) एक अच्छा विचार नहीं है। मुझे लगता है कि सभी रिकॉर्ड के सदस्यों को फिर से शुरू करना सबसे अच्छा तरीका है। इस तरह, आप चर लोड लोड रखें।

यदि आप जितनी संभव हो उतनी छोटी मेमोरी का उपयोग करने के लिए, अब आप चर की आवश्यकता नहीं है, तो आप SetLength (transactions,0) का उपयोग कर सकते हैं। बेशक, यदि आपको कार्यक्रम में कहीं और फिर से इसकी आवश्यकता है, तो आप इसकी लंबाई को फिर से समायोजित कर सकते हैं, मान लीजिए कि आप इसे जानते हैं।

आपको किसी भी चीज़ को अंतिम रूप देने की आवश्यकता नहीं है, क्योंकि यह एक रिकॉर्ड है, कक्षा नहीं। रिकॉर्ड्स में कन्स्ट्रक्टर या विध्वंसक, कक्षाओं की तरह नहीं हैं।

+0

* "आप इसकी लंबाई को फिर से समायोजित कर सकते हैं" * - लेकिन याद रखें कि फिर आपको संभवतः सभी पुरानी वस्तुओं को उनकी सभी स्थिर सामग्री और गतिशील सामग्री (तार, डायन सरणी) के साथ कॉपी किया जाएगा, शायद उनकी रेफरी गिनती होगी बढ़ा घटा। यही कारण है कि मैं कुछ मामलों में लंबाई बदलने से पहले पूर्ण सरणी deallocation का उपयोग करें। * "आपको कुछ भी अंतिम रूप देने की आवश्यकता नहीं है, क्योंकि यह एक रिकॉर्ड है, न कि कक्षा" * - यह केवल तभी सही है जब सभी रिकॉर्ड फ़ील्ड सरल प्रकार हों (स्ट्रिंग/डाइन एरे/इंटरफेस नहीं)। – Fr0sT

10

सरणी लंबाई को शून्य पर सेट करना सरणी को नष्ट कर देगा, जो "सरणी को लोड रखने" की आपकी इच्छा के मुकाबले चला जाता है। हालांकि, यह सभी रिकॉर्ड्स और उनके तारों के लिए स्मृति को मुक्त करेगा (किसी भी तार के लिए जिसका संदर्भ गणना उस समय 1 है)।

यदि आप केवल स्ट्रिंग के लिए मेमोरी मुक्त करना चाहते हैं, लेकिन रिकॉर्ड मेमोरी आवंटित रखें (क्योंकि आप तुरंत बाद में रिकॉर्ड के दूसरे सेट को आवंटित करने की योजना बना रहे हैं, और आप रिलीज़ करने और फिर से आवंटित करने की बर्बादी नहीं चाहते हैं एक ही स्मृति), तो आप केवल स्ट्रिंग सदस्यों को साफ़ कर सकते हैं, लेकिन आपके लिए ऐसा करने के लिए कोई भी लाइब्रेरी कॉल नहीं है। इसके बजाय, आपको एक लूप लिखना होगा और प्रत्येक रिकॉर्ड के फ़ील्ड को स्वयं साफ़ करना होगा।

for i := 0 to High(transactions) do begin 
    transactions[i].alias := ''; 
    transactions[i].description := ''; 
end; 

अगर वहाँ समाशोधन जरूरत है कि रिकॉर्ड में क्षेत्रों के बहुत सारे हैं, तो यह अधिक सरणी के प्रत्येक तत्व के लिए एक डिफ़ॉल्ट TTransaction मान देना सुविधाजनक हो सकता है। आप Default फ़ंक्शन का उपयोग कर सकते हैं, या डेल्फी के पुराने संस्करणों में आप एक TTransaction अपने सभी क्षेत्रों स्पष्ट पहले से ही है कि घोषणा कर सकते हैं:

const 
    ClearTransaction: TTransaction = (alias: ''; description: ''; creation: 0; count: 0); 

for i := 0 to High(transactions) do 
    transactions[i] := ClearTransaction; 
    // or 
    transactions[i] := Default(TTransaction); 
+0

मुझे लगता है कि यह करने के लिए सबसे अच्छा है ... चूंकि वह उपयोगकर्ता है जो सभी डेटा को रीयलोड करना चाहता है, तो मुझे पता था कि रिकॉर्ड प्रकार एक संरचना है और आदिम प्रकार के मामले में, यही कारण है कि मैंने पूछा। उत्तर – EProgrammerNotFound

+0

उत्तर के लिए धन्यवाद यहां मौजूद प्रश्न के दूसरे भाग में शामिल विषय पर छूने वाला मौजूदा प्रश्न यह है: http://stackoverflow.com/questions/11065821/how-to-properly- free-records-that-contain- विभिन्न प्रकार के इन-डेल्फी-पर-एक बार –

+0

@ डेविड हेफरनन मैंने उस विषय को पढ़ा और यही कारण है कि मैंने अंतिम रूप देने के बारे में पूछा। मैं इतने सारे उत्तरों से उलझन में आया, और वह आदमी अंतिम रूप देने के बारे में बोल रहा है + fillchar ... – EProgrammerNotFound