एक बार "DoStackOverflow" फ़ंक्शन को कॉल करें तुम्हारा कोड और आपको मिलेगा EStackOverflow डेल्फी द्वारा "स्टैक ओवरफ्लो" संदेश के साथ त्रुटि।
समारोह DoStackOverflow: पूर्णांक;
शुरू
परिणाम: = 1 + DoStackOverflow;
समाप्त;
यह "स्टैक" क्या है और ऊपर कोड का उपयोग करके वहां एक अतिप्रवाह क्यों है?
तो, DoStackOverflow फ़ंक्शन पुनरावर्ती रूप से स्वयं को कॉल कर रहा है - बिना "निकास रणनीति" - यह सिर्फ घूमता रहता है और कभी भी बाहर नहीं निकलता है।
एक त्वरित सुधार, आप करेंगे, आपके पास स्पष्ट बग को साफ़ करना है, और यह सुनिश्चित करना है कि फ़ंक्शन किसी बिंदु पर मौजूद है (इसलिए आपका कोड उस फ़ंक्शन को निष्पादित करना जारी रख सकता है जहां से आपने फ़ंक्शन कहा है)।
आप आगे बढ़ते हैं, और आप कभी पीछे मुड़कर नहीं देखते, बग / अपवाद के बारे में परवाह नहीं है क्योंकि यह अब हल हो गया है।
फिर भी, सवाल बना हुआ है: यह स्टैक क्या है और क्यों एक अतिप्रवाह है?
अपने डेल्फी अनुप्रयोगों में मेमोरी
जब आप डेल्फी में प्रोग्रामिंग शुरू करते हैं, तो आप ऊपर वाले की तरह बग का अनुभव कर सकते हैं, आप इसे हल करेंगे और आगे बढ़ेंगे। यह एक मेमोरी आवंटन से संबंधित है। जब तक आप ज्यादातर समय मेमोरी आवंटन की परवाह नहीं करेंगे आप क्या बनाते हैं.
जैसा कि आप डेल्फी में अधिक अनुभव प्राप्त करते हैं, आप अपनी खुद की कक्षाएं बनाना शुरू करते हैं, उन्हें त्वरित करते हैं, स्मृति प्रबंधन और समान रूप से देखभाल करते हैं।
आप उस बिंदु पर पहुंच जाएंगे जहां आप पढ़ेंगे, सहायता में, कुछ इस तरह "स्थानीय चर (प्रक्रियाओं और कार्यों के भीतर घोषित) एक आवेदन में रहते हैं ढेर." और भी कक्षाएं संदर्भ प्रकार हैं, इसलिए उन्हें असाइनमेंट पर कॉपी नहीं किया जाता है, वे संदर्भ द्वारा पारित किए जाते हैं, और उन्हें आवंटित किया जाता है ढेर.
तो, "स्टैक" क्या है और "हीप" क्या है?
ढेर बनाम ढेर
विंडोज पर अपना एप्लिकेशन चला रहे हैं, मेमोरी में तीन क्षेत्र हैं जहां आपका एप्लिकेशन डेटा संग्रहीत करता है: वैश्विक मेमोरी, हीप, और स्टैक।
वैश्विक चर (उनके मूल्य / डेटा) को वैश्विक मेमोरी में संग्रहीत किया जाता है। वैश्विक चर के लिए मेमोरी आपके एप्लिकेशन द्वारा आरक्षित होती है जब प्रोग्राम शुरू होता है और आपके प्रोग्राम के समाप्त होने तक आवंटित रहता है। वैश्विक चर के लिए मेमोरी को "डेटा सेगमेंट" कहा जाता है।
चूँकि वैश्विक स्मृति केवल एक बार आवंटित की जाती है और कार्यक्रम समाप्ति पर मुक्त कर दी जाती है, हम इस लेख में इसकी परवाह नहीं करते हैं।
स्टैक और हीप वह है जहाँ डायनेमिक मेमोरी एलोकेशन होता है: जब आप किसी फंक्शन के लिए वैरिएबल बनाते हैं, जब आप एक वर्ग का एक उदाहरण बनाते हैं जब आप किसी फ़ंक्शन को पैरामीटर भेजते हैं और इसके परिणाम का उपयोग / पास करते हैं मूल्य।
स्टैक क्या है?
जब आप किसी फ़ंक्शन के अंदर एक वैरिएबल की घोषणा करते हैं, तो वेरिएबल को होल्ड करने के लिए आवश्यक मेमोरी स्टैक से आवंटित की जाती है। आप बस "var x: पूर्णांक" लिखते हैं, अपने फ़ंक्शन में "x" का उपयोग करते हैं, और जब फ़ंक्शन बाहर निकलता है, तो आप स्मृति आवंटन के बारे में परवाह नहीं करते हैं और न ही मुक्त करते हैं। जब चर दायरे से बाहर हो जाता है (कोड फ़ंक्शन को बाहर कर देता है), तो स्टैक पर ली गई मेमोरी को मुक्त कर दिया जाता है।
स्टैक मेमोरी को गतिशील रूप से एलआईएफओ ("आखिरी में पहले बाहर") दृष्टिकोण का उपयोग करके आवंटित किया गया है।
में डेल्फी कार्यक्रम, स्टैक मेमोरी द्वारा उपयोग किया जाता है
- स्थानीय दिनचर्या (विधि, प्रक्रिया, कार्य) चर।
- नियमित पैरामीटर और वापसी प्रकार।
- विंडोज एपीआई फ़ंक्शन कहता है।
- रिकॉर्ड्स (यही कारण है कि आपको स्पष्ट रूप से रिकॉर्ड प्रकार का एक उदाहरण बनाने की आवश्यकता नहीं है)।
आपको मेमोरी को स्टैक पर स्पष्ट रूप से मुक्त करने की आवश्यकता नहीं है, क्योंकि मेमोरी आपके लिए ऑटो-जादुई रूप से आवंटित की जाती है, जब आप उदाहरण के लिए, किसी फ़ंक्शन के लिए स्थानीय चर घोषित करते हैं। जब फ़ंक्शन बाहर निकलता है (कभी-कभी डेल्फी कंपाइलर ऑप्टिमाइज़ेशन के कारण भी) तो चर के लिए मेमोरी ऑटो-जादुई रूप से मुक्त हो जाएगी।
स्टैक मेमोरी का आकार डिफ़ॉल्ट रूप से, आपके लिए पर्याप्त बड़े (जितने जटिल हैं) डेल्फी कार्यक्रम। आपके प्रोजेक्ट के लिए लिंकर विकल्पों पर "अधिकतम स्टैक आकार" और "न्यूनतम स्टैक आकार" मान डिफ़ॉल्ट मान निर्दिष्ट करते हैं - 99.99% में आपको इसे बदलने की आवश्यकता नहीं होगी।
मेमोरी ब्लॉकों के ढेर के रूप में एक स्टैक के बारे में सोचो। जब आप स्थानीय वैरिएबल की घोषणा / उपयोग करते हैं, तो डेल्फी मेमोरी मैनेजर ब्लॉक को ऊपर से उठाएगा, इसका उपयोग करेगा, और जब ज़रूरत नहीं होगी, तो इसे वापस स्टैक पर लौटा दिया जाएगा।
स्टैक से स्थानीय वैरिएबल मेमोरी का उपयोग करने पर, घोषित किए जाने पर स्थानीय वैरिएबल को प्रारंभ नहीं किया जाता है। किसी फ़ंक्शन में एक वैरिएबल "var x: पूर्णांक" घोषित करें और जब आप फ़ंक्शन में प्रवेश करते हैं तो केवल मूल्य पढ़ने की कोशिश करें - x में कुछ "अजीब" गैर-शून्य मान होगा। इसलिए, उनके मूल्य को पढ़ने से पहले अपने स्थानीय चरों के लिए हमेशा (या मूल्य निर्धारित करें) आरंभ करें।
LIFO के कारण, स्टैक (मेमोरी एलोकेशन) ऑपरेशन तेज होते हैं क्योंकि स्टैक का प्रबंधन करने के लिए केवल कुछ ऑपरेशन (पुश, पॉप) की आवश्यकता होती है।
क्या है?
ढेर स्मृति का एक क्षेत्र है जिसमें गतिशील रूप से आवंटित स्मृति संग्रहीत होती है। जब आप एक वर्ग का एक उदाहरण बनाते हैं, तो मेमोरी को ढेर से आवंटित किया जाता है।
डेल्फी कार्यक्रमों में, ढेर स्मृति का उपयोग / कब किया जाता है
- एक वर्ग का एक उदाहरण बनाना।
- गतिशील सरणियों का निर्माण और आकार बदलना।
- GetMem, FreeMem, New and Dispose () का उपयोग करके मेमोरी को स्पष्ट रूप से आवंटित करना।
- एएनएसआई / विस्तृत / यूनिकोड स्ट्रिंग्स, वेरिएंट, इंटरफेस (डेल्फी द्वारा स्वचालित रूप से प्रबंधित) का उपयोग करना।
हीप मेमोरी में कोई अच्छा लेआउट नहीं है जहां कुछ ऑर्डर होगा, मेमोरी के ब्लॉक आवंटित कर रहा है। ढेर मार्बल्स की तरह दिखते हैं। ढेर से मेमोरी आवंटन यादृच्छिक है, यहां से एक ब्लॉक वहां से एक ब्लॉक है। इस प्रकार, ढेर के संचालन की तुलना में ढेर संचालन थोड़ा धीमा है।
जब आप एक नया मेमोरी ब्लॉक मांगते हैं (यानी एक वर्ग का एक उदाहरण बनाते हैं), डेल्फी मेमोरी मैनेजर आपके लिए यह काम करेगा: आपको एक नया मेमोरी ब्लॉक या एक इस्तेमाल किया हुआ और एक त्याग दिया जाएगा।
ढेर में सभी आभासी मेमोरी होती है (रैम और डिस्क स्थान).
मैन्युअल रूप से आवंटित स्मृति
अब जब मेमोरी के बारे में सब कुछ स्पष्ट है, तो आप सुरक्षित रूप से (ज्यादातर मामलों में) उपरोक्त को अनदेखा कर सकते हैं और बस डेल्फी प्रोग्राम लिखना जारी रख सकते हैं जैसा कि आपने कल किया था।
बेशक, आपको याद रखना चाहिए कि कब और कैसे मैन्युअल रूप से / मुक्त मेमोरी आवंटित करना है।
"EStackOverflow" (लेख की शुरुआत से) उठाया गया था क्योंकि DoStackOverflow के प्रत्येक कॉल के साथ मेमोरी के एक नए सेगमेंट का उपयोग स्टैक से किया गया है और स्टैक की सीमाएँ हैं। इतना सरल है।