6

अगर मैं निम्नलिखित बयान है ढेर पर मेमोरी आवंटित करने: गतिशील ढेर परसी ++ - का उपयोग करते हुए 'नई'

int *x = new int;

इस मामले में, मैं आवंटित स्मृति। दूसरे शब्दों में, अब मेरे पास मेमोरी पता int ऑब्जेक्ट के लिए है।

delete x;

इसका मतलब है कि मैं ढेर पर स्मृति पता freed up:

कहते हैं कि उसके बाद मैं निम्नलिखित बनाया है। उसके बाद

कहते हैं मैं फिर से निम्नलिखित था:

int *x = new int;

विल xही वर्ष स्मृति पता यह ढेर पर की ओर इशारा करने के लिए बिंदु से पहले हटा दी गई?

क्या होगा यदि मैं delete से पहले ऐसा किया:

x = NULL;

और, तो ऐसा किया:

int *x = new int;

विल x ढेर पर आ स्मृति पता इंगित अन्य से पुराना वाला?

धन्यवाद।

+1

केवल पॉइंटर को 'न्यूल' पर सेट करके, आप हैं इसे हटा नहीं रहा यदि आप फिर 'नया int' करते हैं, तो पुरानी मेमोरी अभी भी उपयोग में होगी (बिना पॉइंटर के - यह एक मेमोरी लीक है), और निश्चित रूप से 'नया' * हमेशा * * * * को इंगित करेगा - इसलिए नाम। –

उत्तर

1

नहीं, ऐसी कोई गारंटी नहीं है। यह पूरी तरह से आपके स्मृति अनुरोध को पूरा करने के लिए उपयोग किए गए आवंटक पर निर्भर करता है। हालांकि, सी ++ शक्तिशाली जानवर होने के नाते यह है कि, आप नए ऑपरेटर को ओवरराइड करते हैं। आप एक कस्टम आवंटक (मेमोरी मैनेजमेंट) बना सकते हैं जो स्मृति को एक निश्चित तरीके से प्रदान करता है, जो कभी-कभी बहुत उपयोगी होता है।

+0

क्या आप एक उदाहरण दे सकते हैं - 'नया' इस्तेमाल किए बिना स्मृति आवंटित कैसे किया जाएगा और कस्टम आवंटन के लिए उपयोग किया जाता है? –

+0

कस्टम आवंटकों का अनुक्रमिक स्मृति की निश्चित मात्रा प्रदान करने के लिए उपयोग किया जा सकता है। प्रदर्शन के अनुसार और आम तौर पर गेम में यह एक अच्छा अनुक्रमिक स्मृति पहुंच पैटर्न के लिए बेहतर है। एक कचरा कलेक्टर (स्वचालित मेमोरी प्रबंधन) आमतौर पर समय पर एक साथ इस आवंटन को आवंटित करके प्रदान करता है। एक साधारण रैखिक आवंटक वही कर सकता है और यह चीजों को छोटे ढेर पर भी स्थानांतरित कर सकता है क्योंकि छेद को रोकने के लिए चीजों को हटाया जाता है और भविष्य में स्मृति प्रदर्शन में सुधार के लिए अन्य हार्डवेयर बाधाओं को ध्यान में रखता है। –

+0

अधिक उदाहरणों के लिए आप यह पृष्ठ देख सकते हैं http://www.cprogramming.com/tutorial/operator_new.html मुझे पूरा यकीन है कि डिफ़ॉल्ट आवंटक को ओवरराइड करना संभव है, जिसके द्वारा आप 'नए int' ऑपरेशन को ओवरराइड करेंगे। –

1

नहीं, दूसरा new int; से लौटा गया सूचक वैध लिखने योग्य पते के भीतर कहीं भी इंगित कर सकता है। इस बात की कोई गारंटी नहीं है कि पहले से हटाए गए क्षेत्र का उपयोग किया जाएगा (असल में ज्यादातर बार ऐसा नहीं हो सकता है क्योंकि हीप मैनेजर कुछ समय बाद वास्तविक स्मृति को रिलीज़ करना चुन सकता है)।

1

जब आप ऐसा करते से पहले हटा दें:

x = NULL; 

तो यह एक स्मृति रिसाव है। आप स्मृति खो देते हैं जो कुछ भी नहीं करता है, और आप मुक्त नहीं कर सकते क्योंकि आपने इसका पता खो दिया है। (आप एक शून्य सूचक को हटा सकते हैं, यह कुछ भी नहीं करता है)

ऐसा करने में बहुत अधिक समय हो सकता है जिसके परिणामस्वरूप सिस्टम क्रैश/स्वीकार्य हो जाता है क्योंकि आपकी सभी मेमोरी बर्बाद हो जाती है। (डिस्क पर स्वैप का उपयोग करके बहुत अधिक आदि ... आदि ...)

हटाए जाने के बाद एक ही सटीक नया पता पाने की उम्मीद न करें, फिर एक नया फिर से। हालांकि यह समय-समय पर यादृच्छिक रूप से हो सकता है।

1

1) आप मुक्त होने के बाद, यदि आप एक ही चर का उपयोग करके फिर से आवंटित करते हैं तो आपको कोई गारंटी नहीं है कि आपको स्मृति का एक ही हिस्सा मिल जाएगा। इस बारे में सोचें कि नया कैसे कार्यान्वित किया जाता है, इसे कस्टम आवंटकों का उपयोग करके भी कल्पना की जा सकती है। साथ ही, यह संभव है कि अन्य धागे मुक्त() और नई() कॉल के बीच नए इस्तेमाल किए जाएं और आपकी याददाश्त 'चुरा लिया'

2) ऐसा न करें। आप संदर्भ खो रहे हैं और यदि आप नल पॉइंटर पर डिलीट ऑपरेटर लागू करते हैं तो यह कुछ भी नहीं करेगा। यदि आप अन्य चर पर संदर्भ संग्रहीत नहीं करते हैं तो आपके पास संसाधन रिसाव हो सकता है। यदि आप नए फोन फिर से यह निश्चित रूप से कहीं और आवंटित करेगा यह सोचते हैं कोई क्षेत्र से पहले नए()

10

दी पहले मामले में पुनः आवंटित की जाती है कि, आप फिर स्मृति के एक ही ब्लॉक मिल सकता है, लेकिन वहाँ इसके बारे में कोई निश्चितता है ।

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

2

जो आप पूछ रहे हैं वह पूरी तरह से अनिर्धारित है (सी/सी ++ मानक के अनुसार) और कार्यान्वयन पर निर्भर करेगा।

यह आपके लिए संकलक के आपके संस्करण के साथ परीक्षण करना आसान होना चाहिए।

आपको यह ध्यान रखना चाहिए कि इस व्यवहार के नतीजे पर कभी निर्भर नहीं होना चाहिए क्योंकि यह किसी भी समय/किसी भी ओएस/आपके कंपाइलर के अपग्रेड के साथ बदल सकता है।

मुझे लगता है कि क्या हो सकता है, आपको वही पता मिलेगा, जब तक आपके पास आपके प्रोग्राम में अन्य थ्रेड नहीं हैं जो एक ही समय के दौरान आवंटित हो रहे हैं। लेकिन फिर भी आपको एक ही पता मिल सकता है, यदि आपके कंपाइलर का विशेष मॉलोक कार्यान्वयन अलग-अलग धागे के लिए अलग-अलग ढेर का उपयोग करने का निर्णय लेता है (जो पेर्फ के मामले में बेहतर है)