सी ++ में गतिशील मेमोरी आवंटन

Si Mem Gatisila Memori Avantana



आम तौर पर, C++ प्रोग्रामिंग लैंग्वेज में सोर्स कोड का उपयोग करते समय, एक कंपाइलर डेटा के स्टोरेज के लिए वेरिएबल को मैन्युअल रूप से मेमोरी आवंटित करता है। इसे स्टैटिक मेमोरी का आवंटन कहा जाता है। यह एक निश्चित मेमोरी है जिसे एक बार घोषित करने के बाद बदला नहीं जा सकता है। इस प्रकार के मेमोरी आवंटन के लिए, ऑपरेटिंग सिस्टम डेटा स्टोर करने के लिए स्टैक का उपयोग करता है। स्टैटिक एलोकेशन में, मेमोरी को सोर्स कोड के एक्जीक्यूट होने से पहले आवंटित किया जाता है।

जबकि डायनेमिक मेमोरी एलोकेशन में, मेमोरी को तब आवंटित किया जाता है जब निष्पादन शुरू हो जाता है। यह मेमोरी प्रोग्रामर द्वारा मैन्युअल रूप से रन-टाइम पर आवंटित की जाती है, जिसे C++ में रन-टाइम मेमोरी आवंटन के रूप में भी जाना जाता है। डायनेमिक मेमोरी के आकार को कार्यक्रम में किसी भी स्थिति में बदला जा सकता है क्योंकि घोषणा के समय, हम उस आकार का उल्लेख नहीं करते हैं जिसे तय किया जा सकता है। हम केवल वेरिएबल को सीधे मान प्रदान करते हैं।

सामान्य चर के लिए स्मृति आवंटन का अंतर

सामान्य चर में, एक कंपाइलर द्वारा आवंटित की गई मेमोरी को स्वचालित रूप से आवंटित और हटा दिया जाता है। जब प्रोग्रामर द्वारा मेमोरी को गतिशील रूप से आवंटित किया जाता है, तो उसे तब मेमोरी को हटाना या हटाना पड़ता है जब स्रोत कोड के आगे के निष्पादन में इसका कोई उपयोग नहीं होता है। यह स्थिति 'मेमोरी लीक' का कारण बनती है जब प्रोग्राम को समाप्त कर दिया जाता है जबकि मेमोरी को हटाया नहीं जाता है।







गतिशील आवंटन के लिए ऑपरेटर

C++ में, दो ऑपरेटर मेमोरी एलोकेशन और डीलोकेशन में मदद करते हैं: 'नया' और 'डिलीट' जिनका उपयोग बेहतर तरीके से मेमोरी के आवंटन और डीलोकेशन के लिए किया जाता है।



नया ऑपरेटर

यह मेमोरी आवंटन की मांग को दर्शाता है। नया ऑपरेटर मेमोरी को इनिशियलाइज़ करता है और पर्याप्त मेमोरी उपलब्ध होने पर उस आवंटित मेमोरी का पता पॉइंटर वैरिएबल को लौटाता है।



सूचक वस्तु = नया जानकारी - प्रकार ;

ऑपरेटर हटाएं

नए ऑपरेटर की तरह, आवंटित मेमोरी को हटाने के लिए एक डिलीट ऑपरेटर का उपयोग किया जाता है। सी ++ में, प्रोग्रामर इस ऑपरेटर को डीलोकेशन के लिए उपयोग कर सकता है।





# पॉइंटर_वेरिएबल हटाएं;

उदाहरण 1

इस उदाहरण में, हम दो पॉइंटर्स पेश करेंगे: एक इंटीजर टाइप पॉइंटर है और दूसरा फ्लोट पॉइंटर है। पॉइंटर्स को उनके साथ एक तारक चिह्न का उपयोग करके प्रारंभ किया जाता है।

# इंट * पॉइंटइंट;
# फ्लोट * पॉइंटफ्लोट;

इन दो प्रिंटर का उपयोग करके, हम गतिशील रूप से मेमोरी आवंटित करेंगे।



डायनेमिक आवंटन में पॉइंटर्स की भूमिका:
स्टोरेज स्पेस की मेमोरी को ब्लॉक के रूप में विकसित किया जाता है। जब भी हम कोई प्रोग्राम निष्पादित करते हैं या कोई ऑपरेशन करते हैं, तो उस विशिष्ट उद्देश्य के लिए मेमोरी आवंटित की जाती है। उस मेमोरी का एक विशेष पता होता है जो उस प्रोग्राम से जुड़ा होता है जो यह पहचानता है कि उस मेमोरी को कौन सी प्रक्रिया या प्रोग्राम की अनुमति है। किसी भी मेमोरी स्लॉट को उस पते के माध्यम से एक्सेस किया जाता है जिससे वह संबंधित है। तो यह एड्रेस पॉइंटर्स के माध्यम से स्टोर किया जाता है। संक्षेप में, हमें मेमोरी तक पहुँचने के लिए पॉइंटर्स की आवश्यकता होती है और उसी तरह, किसी भी कार्य के लिए मेमोरी का एक विशिष्ट भाग आवंटित करने के लिए। पतों को स्टोर करने के लिए पॉइंटर्स की आवश्यकता होती है।

चूंकि मैन्युअल आवंटन में स्मृति के गतिशील आवंटन के लिए 'नया' कीवर्ड का उपयोग किया जाता है, स्मृति को संकलक द्वारा आवंटित किया जाता है। हमें रन टाइम पर मेमोरी आवंटित करने की आवश्यकता नहीं होती है। लेकिन चूंकि डायनेमिक आवंटन यादृच्छिक है, हमें पॉइंटर्स की पहचान करने की आवश्यकता है और बाध्यकारी प्रक्रिया के लिए, इस नए ऑपरेटर का उपयोग किया जाता है।

# पॉइंटिन्ट = नया इंट;

इसी तरह फ्लोटिंग पॉइंटर भी बाउंड होता है। बाइंडिंग प्रक्रिया के बाद, हम किसी भी ऑपरेशन के लिए बुक की जाने वाली मेमोरी को कोई वैल्यू असाइन करेंगे। पॉइंटर घोषित करके, हम मेमोरी को एक विशिष्ट मान प्रदान करते हैं।

# * पॉइंटइंट = 50;

बिंदु फ़्लोट्स के लिए एक फ़्लोट मान भी घोषित किया जाता है। असाइन करने के बाद मान प्रदर्शित करें।

जैसा कि हमने चर्चा की है, 'नया' ऑपरेटर का उपयोग आवंटन के लिए किया जाता है जबकि 'डिलीट' का उपयोग मेमोरी को हटाने के लिए किया जाता है। इसलिए एक बार जब आप कोड में कार्य या संचालन पूरा कर लेते हैं, तो हम उस मेमोरी को हटा देंगे जिसे हमने कार्य के लिए आवंटित किया है।

स्मृति के उस हिस्से को हटाना बेहतर है ताकि कोई अन्य प्रक्रिया इसका लाभ उठा सके। हम इस आवंटन को दोनों पॉइंटर्स पर लागू करेंगे।

बिंदु हटाएं पानी पर तैरना ;

एक बार जब आप पाठ संपादक पर कोड सहेज लेते हैं, तो उबंटू टर्मिनल आपको फ़ाइल के अंदर स्रोत कोड को g++ कंपाइलर के माध्यम से निष्पादित करने की अनुमति देता है।

$ g++ -ओ मेम mem.c
$ ./मेम

निष्पादन पर, आप मेमोरी को निर्दिष्ट मान देखेंगे।

उदाहरण 2

इस उदाहरण में उपयोगकर्ता सहभागिता की भागीदारी है। हम एक संख्या चर लेंगे जिसमें उपयोगकर्ता से एक मान होगा। यह कार्यक्रम छात्रों के जीपीए में परिणाम संग्रहीत करेगा। सभी परिणाम रन टाइम पर सहेजे जाएंगे।

जब उपयोगकर्ता छात्रों की संख्या दर्ज करता है, तो प्रत्येक संख्या के लिए मेमोरी आवंटित की जाती है। एक फ्लोट टाइप पॉइंटर को यहां इनिशियलाइज़ किया गया है जिसका उपयोग परिणामों के मेमोरी आवंटन में किया जाएगा।

हम पॉइंटर को फ्लोट में लेते हैं क्योंकि GPA डेसीमल नोटेशन में है। हम GPA के लिए एक सूचक प्रकार की सरणी लेते हैं क्योंकि इसका परिणाम कई छात्रों के लिए हो सकता है।

पं = नया पानी पर तैरना [ एक पर ]

'नया' कीवर्ड वाला यह पॉइंटर ऐरे निष्पादन को मेमोरी से बांध देगा। प्रत्येक छात्र के लिए GPA दर्ज किया जाएगा। जैसा कि हम उन छात्रों की संख्या से परिचित नहीं हैं जिन्हें उपयोगकर्ता जोड़ना चाहता है, हमने दर्ज संख्या तक GPA दर्ज करने के लिए लूप का उपयोग किया। लूप की प्रत्येक पुनरावृत्ति में, उपयोगकर्ता से छात्र की पहचान करने वाले परिणाम दर्ज करने के लिए कहा जाता है। एक बार परिणाम सहेजे जाने के बाद, हम फिर से छात्रों के सभी GPA प्रदर्शित करने के लिए एक लूप का उपयोग करेंगे। अंत में, सूचक प्रकार सरणी हटा दी जाती है, क्योंकि गतिशील भंडारण का उद्देश्य पूरा हो गया था।

मिटाना [ ] पीटीआर ;

अब हम उपर्युक्त कोड को निष्पादित करेंगे। उपयोगकर्ता से पहले छात्रों की संख्या दर्ज करने का अनुरोध किया जाएगा। फिर प्रत्येक छात्र के लिए जीपीए दर्ज किया जाएगा।

उदाहरण 3

यह उदाहरण क्लास के ऑब्जेक्ट के लिए नए और डिलीट ऑपरेटर्स का उपयोग करता है। इस वर्ग में पूर्णांक प्रकार का एक निजी चर होता है जो आयु को संग्रहीत करता है। एक वर्ग के सार्वजनिक भाग में, कंस्ट्रक्टर बनाया जाता है जो उम्र को '10' की संख्या में आरंभ करेगा। यहां एक अन्य फ़ंक्शन का उपयोग किया जाता है जो उस उम्र को प्रदर्शित करेगा जो कि कंस्ट्रक्टर में आरंभीकृत है।

अब हम डायनेमिक आवंटन के मुख्य कार्यक्रम की ओर बढ़ेंगे। वर्ग की वस्तु गतिशील रूप से बनाई गई है।

विद्यार्थी * पीटीआर = नया छात्र ( ) ;

जब ऑब्जेक्ट बन जाता है, तो कंस्ट्रक्टर अपने आप लागू हो जाएगा। उम्र जानने के लिए फंक्शन कॉल किया जाएगा। यह पीआरटी के माध्यम से किया जाएगा।

पं - > getAge ( ) ;

और अंत में, स्मृति जारी की जाएगी।

निष्कर्ष

कंपाइलर द्वारा पहचाने गए निश्चित स्टोरेज के बजाय प्रोग्रामर द्वारा रन टाइम एक्जीक्यूशन पर डायनेमिक मेमोरी एलोकेशन आवंटित किया जाता है। यह आवंटन यादृच्छिक आधार पर होता है और इसका उपयोग करने के बाद इसे समाप्त किया जा सकता है। जबकि, ज्यादातर मामलों में, हटाने से पहले, निष्पादन प्रक्रिया बंद हो जाती है और यह गतिशील आवंटन स्मृति रिसाव का कारण बनता है। हमने इस परिघटना को C++ प्रोग्रामिंग लैंग्वेज का उपयोग करते हुए उबंटू लिनक्स सिस्टम में विभिन्न तरीकों से लागू किया है।