Foo* set = new Foo[100];
// ...
delete [] set;
आप सरणी की सीमाओं को पास नहीं करते हैं delete[]
। लेकिन वह जानकारी कहां संग्रहीत है? क्या यह मानकीकृत है?
Foo* set = new Foo[100];
// ...
delete [] set;
आप सरणी की सीमाओं को पास नहीं करते हैं delete[]
। लेकिन वह जानकारी कहां संग्रहीत है? क्या यह मानकीकृत है?
जवाबों:
जब आप हीप पर मेमोरी आवंटित करते हैं, तो आपका एलोकेटेटर आपके द्वारा आवंटित की गई मेमोरी का ट्रैक रखेगा। यह आमतौर पर मेमोरी से पहले एक "हेड" खंड में संग्रहीत किया जाता है जिसे आपको आवंटित किया जाता है। इस तरह से जब मेमोरी को खाली करने का समय होता है, तो डी-एलाटेटर को पता होता है कि मेमोरी कितनी खाली करनी है।
free
जानता है कि मेमोरी को कितना कम करना है"। हां, मेमोरी ब्लॉक का आकार "कहीं न कहीं" malloc
(सामान्य रूप से ब्लॉक में) संग्रहीत होता है, इसलिए यह free
पता है कि कैसे । हालाँकि, new[]
/ delete[]
एक अलग कहानी है। उत्तरार्द्ध मूल रूप से malloc
/ के शीर्ष पर काम करते हैं free
। new[]
यह मेमोरी ब्लॉक (स्वतंत्र रूप से malloc
) में बनाए गए तत्वों की संख्या को भी संग्रहीत करता है , ताकि बाद में delete[]
उस संख्या को पुनः प्राप्त कर सकें और उचित संख्या में विध्वंसक कॉल कर सकें ।
malloc
) और तत्व गणना (द्वारा new[]
)। ध्यान दें, पूर्व का उपयोग बाद की गणना करने के लिए नहीं किया जा सकता है, क्योंकि सामान्य स्थिति में मेमोरी ब्लॉक का आकार अनुरोधित आकार की सरणी के लिए वास्तव में आवश्यक से बड़ा हो सकता है। यह भी ध्यान दें कि सरणी तत्व काउंटर केवल गैर-तुच्छ विध्वंसक प्रकार के लिए आवश्यक है। तुच्छ विध्वंसक के साथ प्रकारों के लिए काउंटर द्वारा संग्रहीत नहीं किया जाता है new[]
और निश्चित रूप से, द्वारा पुनर्प्राप्त नहीं किया जाता है delete[]
।
संकलक के लिए दृष्टिकोणों में से एक थोड़ा अधिक स्मृति आवंटित करना और एक प्रमुख तत्व में तत्वों की गिनती को संग्रहीत करना है।
उदाहरण यह है कि यह कैसे किया जा सकता है:
यहाँ
int* i = new int[4];
संकलक sizeof(int)*5
बाइट आवंटित करेगा ।
int *temp = malloc(sizeof(int)*5)
पहले sizeof(int)
बाइट्स में "4" स्टोर करेगा
*temp = 4;
और सेट करें i
i = temp + 1;
तो i
5 नहीं, 4 तत्वों की एक सरणी को इंगित करेगा।
और विलोपन
delete[] i;
निम्नलिखित तरीके से संसाधित किया जाएगा:
int *temp = i - 1;
int numbers_of_element = *temp; // = 4
... call destructor for numbers_of_element elements
... that are stored in temp + 1, temp + 2, ... temp + 4 if needed
free (temp)
जानकारी मानकीकृत नहीं है। हालाँकि जिन प्लेटफार्मों पर मैंने इस जानकारी पर काम किया है, वे पहले तत्व से ठीक पहले मेमोरी में संग्रहीत हैं। इसलिए आप इसे सैद्धांतिक रूप से एक्सेस कर सकते हैं और इसका निरीक्षण कर सकते हैं, हालांकि यह इसके लायक नहीं है।
इसके अलावा आपको नई [] के साथ मेमोरी आवंटित करने पर डिलीट [] का उपयोग करना चाहिए, क्योंकि डिलीट का ऐरे संस्करण जानता है कि (और कहां) इसे सही मात्रा में मेमोरी को खाली करने की जरूरत है - और उचित संख्या में डिस्ट्रक्टर्स को कॉल करें वस्तुओं के लिए।
मूल रूप से इसकी स्मृति में व्यवस्थित:
[जानकारी] [मेम आप के लिए पूछा ...]
जानकारी आपके संकलक द्वारा उपयोग की जाने वाली संरचना कहां है, आवंटित की गई मेमोरी की मात्रा को स्टोर करने के लिए, और क्या नहीं।
हालांकि यह कार्यान्वयन पर निर्भर है।
यह संकलक होने के लिए C ++ मानक में परिभाषित किया गया है। जिसका मतलब है कंपाइलर मैजिक। यह कम से कम एक प्रमुख मंच पर गैर-तुच्छ संरेखण प्रतिबंधों के साथ टूट सकता है।
आप वास्तविक कार्यान्वयन के बारे में सोच सकते हैं , जो delete[]
केवल उन बिंदुओं के लिए परिभाषित किया गया है new[]
, जिनके द्वारा लौटाए गए सूचक नहीं हो सकते हैं operator new[]
। जंगली में एक कार्यान्वयन पहले से लौटे हुए इंट काउंट को स्टोर करना है operator new[]
, और new[]
एक पॉइंटर ऑफ़सेट अतीत को वापस करना है। (यही कारण है कि गैर-तुच्छ संरेखण टूट सकते हैं new[]
।)
ध्यान रखें कि operator new[]/operator delete[]
! = new[]/delete[]
।
इसके अलावा, यह ऑर्थोगोनल है कि सी किस प्रकार स्मृति द्वारा आवंटित आकार को जानता है malloc
।
क्योंकि 'डिलीट' किए जाने वाले एरे को 'नए' ऑपरेटर के एकल उपयोग के साथ बनाया जाना चाहिए था। 'नए' ऑपरेशन को उस जानकारी को ढेर पर रखना चाहिए था। अन्यथा, नए का अतिरिक्त उपयोग कैसे होगा जहां ढेर समाप्त होता है?
यह मानकीकृत नहीं है। Microsoft के रनटाइम में नया ऑपरेटर मॉलॉक () का उपयोग करता है और डिलीट ऑपरेटर मुफ्त () का उपयोग करता है। तो, इस सेटिंग में आपका प्रश्न निम्नलिखित के बराबर है: ब्लॉक के आकार को कैसे मुक्त () जानते हैं?
सी के रनटाइम में पर्दे के पीछे कुछ बहीखाता चल रहा है।
यह एक अधिक दिलचस्प समस्या है जो आप पहले सोच सकते हैं। यह उत्तर एक संभावित कार्यान्वयन के बारे में है।
सबसे पहले, जबकि कुछ स्तर पर आपके सिस्टम को पता है कि मेमोरी ब्लॉक को कैसे 'फ्री' करना है, अंतर्निहित मॉलोक / फ्री (जो नया / डिलीट / नया [] / डिलीट [] आमतौर पर कॉल करता है) हमेशा याद नहीं रखें कि कितनी मेमोरी है आप पूछते हैं, यह गोल हो सकता है (उदाहरण के लिए, एक बार जब आप 4K से ऊपर होते हैं तो इसे अक्सर अगले 4K-आकार के ब्लॉक तक गोल किया जाता है)।
इसलिए, भले ही मेमोरी ब्लॉक का आकार मिल सकता है, लेकिन यह हमें यह नहीं बताता है कि नए [] एड मेमोरी में कितने मूल्य हैं, क्योंकि यह छोटा हो सकता है। इसलिए, हमें यह बताते हुए एक अतिरिक्त पूर्णांक स्टोर करना होगा कि कितने मूल्य हैं।
EXCEPT, यदि निर्माण किए जा रहे प्रकार में विध्वंसक नहीं है, तो हटाएं [] मेमोरी ब्लॉक को छोड़कर कुछ भी करने की आवश्यकता नहीं है, और इसलिए कुछ भी स्टोर करने की आवश्यकता नहीं है!