2010-01-09 11 views
14

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

लेकिन जब हम गतिशील रूप से आवंटित सरणी को मुक्त करते हैं, तो हम आकार निर्दिष्ट नहीं करते हैं, बल्कि हम केवल "मुक्त पीआरटी" या "हटाएं [] पीटीआर"। सरणी के आकार को कैसे मुक्त या हटाया जा सकता है? क्या हम किसी अन्य चर में सरणी के आकार को संग्रहीत करने से बचने के लिए एक ही योजना का उपयोग कर सकते हैं?

धन्यवाद!

उत्तर

18

हाँ, यह सच है।

delete मेमोरी खंड के आकार को जानता है क्योंकि new अन्य जानकारी के साथ, इसके आकार को शामिल करते हुए, आमतौर पर खंड में अतिरिक्त जानकारी जोड़ता है (जिसमें उपयोगकर्ता को वापस लौटाया जाता है)। ध्यान दें कि यह सब बहुत अधिक कार्यान्वयन विशिष्ट है और आपके कोड द्वारा उपयोग नहीं किया जाना चाहिए।

तो अपने अंतिम प्रश्न का उत्तर देने के लिए: नहीं - हम इसका उपयोग नहीं कर सकते - यह एक कार्यान्वयन विवरण है जो अत्यधिक मंच और संकलक निर्भर है।

typedef long Align; /* for alignment to long boundary */ 

union header { /* block header */ 
    struct { 
    union header *ptr; /* next block if on free list */ 
    unsigned size; /* size of this block */ 
    } s; 

    Align x; /* force alignment of blocks */ 
}; 

typedef union header Header; 

size आवंटित ब्लॉक के आकार है (कि है:


उदाहरण के लिए, नमूना स्मृति allocator कश्मीर & R2 में प्रदर्शन में, इस "शीर्षक" प्रत्येक आवंटित हिस्सा के समक्ष रखा है फिर free, या delete द्वारा उपयोग किया जाता है)।

+1

ध्यान दें कि के बिंदु से आवंटित ब्लॉक का आकार आवंटन कार्यान्वयन का दृष्टिकोण उपयोगकर्ता द्वारा अनुरोध किए गए आकार से बड़ा हो सकता है। –

+0

इसके अलावा, कच्चे अंतर्निहित ब्लॉक के आकार से परे, यदि किसी प्रकार के टी में विनाशक होता है, तो सिस्टम को 'n' को' नया टी [n] '_sewhereewhere_ पर संग्रहीत करना होगा ताकि वह विनाशक 'n' बार कॉल कर सके हटाएं [] 'कहा जाता है। बेशक, यह कैसे और कहाँ स्टोर करता है 'एन' कच्चे ब्लॉक आकार के भंडारण के रूप में विशिष्ट कार्यान्वयन के रूप में बनी हुई है। –

3

यह सच है कि सरणी में सरणी का आकार नहीं है, आपको बाद में उस जानकारी को स्टोर करना होगा। delete या free के माध्यम से सरणी को हटाते समय यह आवंटित आवंटित स्मृति का सूचक होता है। मेमोरी मैनेजर का उपयोग किया जाता है (या तो सिस्टम या अपनी खुद की कस्टम द्वारा ओवरराइडिंग और डिलीट करने से) वह स्मृति क्षेत्र जानता है जो मुक्त हो जाता है, और इसका ट्रैक रखता है। उम्मीद है कि यह समझ में आता है।

2

हाँ, यह सच है। यह एक हिस्सा है कि आपको शायद ही कभी इस से निपटने का प्रयास क्यों करना चाहिए, और इसके बजाय मानक कंटेनर का उपयोग करना चाहिए। एकमात्र समय के साथ इसका निपटारा करने का अर्थ यह है कि यदि आप स्वयं एक कंटेनर को लागू करने का निर्णय लेते हैं (इस मामले में आप आमतौर पर अपने कंटेनर के कार्यान्वयन में आकार की जानकारी ट्रैक करेंगे)।

7

मजाकिया बात यह है कि ऐतिहासिक रूप से यह delete [20] arr; था जैसा कि यह arr = new int[20] है। हालांकि अभ्यास ने साबित किया कि आकार की जानकारी को ऑलोकेटर द्वारा दर्द रहित रूप से संग्रहीत किया जा सकता है, और चूंकि अधिकांश लोग इसका उपयोग करते हैं, फिर भी इसे संग्रहीत करते हैं, इसे मानक में जोड़ा गया था।

अधिक मजेदार और कम ज्ञात क्या है, यह तथ्य यह है कि यह "विस्तारित डिलीट सिंटैक्स" वास्तव में कुछ सी ++ कंपाइलर्स द्वारा समर्थित है (सी ++ 98 मानक के सामने भी गलत होने के बावजूद), हालांकि कोई नहीं इसकी आवश्यकता है

int* arr = new int[20]; 
delete [20] arr; 

इस बारे में दुखद हिस्सा सभी तथापि है, वहाँ अपने स्वयं के उपयोग के लिए है कि पारित कर दिया आकार को पुन: प्राप्त करने के लिए कोई मानक-अनुरूप रास्ता है कि: -/

+0

यह "समर्थित" हो सकता है - यह सी ++ मानक का हिस्सा नहीं है। –

+0

सच है, मैंने अपना जवाब थोड़ा बढ़ाया। मुझे आश्चर्य है कि क्या कोई मानदंड दस्तावेज उपलब्ध है जो दस्तावेज "फीचर" उत्पन्न करता है। –

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