यह कैसे हो सकता है? एक स्थानीय चर की स्मृति अपने समारोह के बाहर दुर्गम नहीं है?
आप एक होटल का कमरा किराए पर लें। आप बेडसाइड टेबल के शीर्ष दराज में एक किताब रखें और सो जाएं। आप अगली सुबह की जांच करते हैं, लेकिन अपनी चाबी वापस देने के लिए "भूल जाते हैं"। तुम चाबी चोरी करो!
एक हफ्ते बाद, आप होटल में लौटते हैं, चेक इन नहीं करते हैं, अपने पुराने कमरे में अपनी चोरी की हुई चाबी, और दराज में देखते हैं। आपकी किताब अभी बाकी है। आश्चर्यजनक!
ऐसे कैसे हो सकता है? यदि आपने कमरा किराए पर नहीं लिया है तो होटल के कमरे की दराज की सामग्री दुर्गम नहीं है?
खैर, जाहिर है कि वास्तविक दुनिया में कोई समस्या नहीं हो सकती है। कोई रहस्यमय बल नहीं है जो आपकी किताब को गायब कर देता है जब आप कमरे में रहने के लिए अधिकृत नहीं होते हैं। और न ही एक रहस्यमय बल है जो आपको चोरी की हुई चाबी के साथ एक कमरे में प्रवेश करने से रोकता है।
आपकी पुस्तक को निकालने के लिए होटल प्रबंधन की आवश्यकता नहीं है । आपने उनके साथ एक अनुबंध नहीं किया जिसमें कहा गया था कि यदि आप सामान पीछे छोड़ते हैं, तो वे इसे आपके लिए छोड़ देंगे। यदि आप इसे वापस पाने के लिए चोरी की हुई चाबी के साथ अपने कमरे में अवैध रूप से फिर से प्रवेश करते हैं, तो होटल सुरक्षा कर्मचारियों को आपको चुपके से पकड़ने की आवश्यकता नहीं है। आपने उनके साथ कोई अनुबंध नहीं किया है, जिसमें कहा गया है कि "यदि मैं अपने घर में वापस घुसने की कोशिश करता हूं" कमरा बाद में, तुम मुझे रोकने के लिए आवश्यक हो। बल्कि, आपने उनके साथ एक अनुबंध पर हस्ताक्षर किए जिसमें कहा गया था कि "मैं बाद में अपने कमरे में वापस नहीं आने का वादा करता हूं", एक अनुबंध जिसे आपने तोड़ दिया ।
इस स्थिति में कुछ भी हो सकता है । किताब हो सकती है - तुम भाग्यशाली हो गए। किसी और की किताब वहां हो सकती है और आपकी होटल की भट्टी में हो सकती है। जब आप अंदर आते हैं, तो आपकी पुस्तक को टुकड़ों में फाड़कर कोई व्यक्ति वहां पहुंच सकता है। होटल पूरी तरह से टेबल और बुक को हटा सकता था और इसे अलमारी के साथ बदल सकता था। पूरा होटल बस के बारे में फाड़ा जा सकता है और एक फुटबॉल स्टेडियम के साथ बदल दिया जा सकता है, और आप एक विस्फोट में मरने जा रहे हैं जब आप चारों ओर चुपके कर रहे हैं।
आप नहीं जानते कि क्या होने जा रहा है; जब आपने होटल से बाहर की जाँच की और बाद में अवैध रूप से उपयोग करने के लिए एक कुंजी चुरा ली, तो आपने एक पूर्वानुमान योग्य, सुरक्षित दुनिया में रहने का अधिकार छोड़ दिया क्योंकि आपने सिस्टम के नियमों को तोड़ने का विकल्प चुना था।
C ++ एक सुरक्षित भाषा नहीं है । यह आपको सिस्टम के नियमों को तोड़ने की सहर्ष अनुमति देगा। यदि आप कुछ अवैध और मूर्खतापूर्ण करने की कोशिश करते हैं, जैसे कि आप एक कमरे में वापस जाने के लिए अधिकृत हैं, तो आप एक डेस्क के माध्यम से अधिकृत नहीं हैं और एक डेस्क के माध्यम से अफवाह कर रहे हैं जो शायद अब भी नहीं है, सी ++ आपको रोकने के लिए नहीं जा रहा है। C ++ की तुलना में सुरक्षित भाषाएं आपकी शक्ति को सीमित करके इस समस्या को हल करती हैं - उदाहरण के लिए, चाबियों पर अधिक कठोर नियंत्रण करके।
अपडेट करें
पवित्र भलाई, इस जवाब पर बहुत ध्यान दिया जा रहा है। (मुझे यकीन नहीं है कि क्यों - मैंने इसे केवल एक "मज़ेदार" थोड़ा सादृश्य माना, लेकिन जो भी हो)।
मैंने सोचा कि यह कुछ और तकनीकी विचारों के साथ इसे अपडेट करने के लिए जर्मन हो सकता है।
कंपाइलर कोड जनरेट करने के व्यवसाय में हैं, जो उस प्रोग्राम द्वारा हेरफेर किए गए डेटा के भंडारण का प्रबंधन करता है। मेमोरी को प्रबंधित करने के लिए कोड जनरेट करने के कई अलग-अलग तरीके हैं, लेकिन समय के साथ दो बुनियादी तकनीकें उलझ गई हैं।
पहला "लंबे समय तक रहने वाले" भंडारण क्षेत्र का कुछ प्रकार है, जहां भंडारण में प्रत्येक बाइट का "जीवनकाल" - अर्थात्, उस समय की अवधि जब यह वैध रूप से कुछ प्रोग्राम चर के साथ जुड़ा हुआ है - आसानी से आगे की भविष्यवाणी नहीं की जा सकती है समय की। संकलक एक "हीप मैनेजर" में कॉल उत्पन्न करता है जो जानता है कि जब यह आवश्यक हो तो गतिशील रूप से भंडारण कैसे आवंटित करें और जब इसकी आवश्यकता न हो तब इसे पुनः प्राप्त करें।
दूसरी विधि एक "अल्पकालिक" भंडारण क्षेत्र है जहां प्रत्येक बाइट के जीवनकाल को अच्छी तरह से जाना जाता है। यहां, जीवनकाल "नेस्टिंग" पैटर्न का पालन करता है। इन अल्पकालिक चर के सबसे लंबे समय तक रहने को किसी भी अन्य अल्पकालिक चर से पहले आवंटित किया जाएगा, और अंतिम रूप से मुक्त किया जाएगा। छोटे-जीवित चर को सबसे लंबे समय तक जीवित रहने के बाद आवंटित किया जाएगा, और उनसे पहले मुक्त कर दिया जाएगा। इन छोटे-जीवित जीवों का जीवनकाल लंबे समय तक जीवित लोगों के भीतर "नेस्टेड" होता है।
स्थानीय चर बाद के पैटर्न का पालन करते हैं; जब कोई विधि दर्ज की जाती है, तो इसके स्थानीय चर जीवंत हो जाते हैं। जब वह विधि किसी अन्य विधि को कॉल करती है, तो नई विधि के स्थानीय चर जीवंत हो जाते हैं। पहले तरीके के स्थानीय चर मृत होने से पहले वे मृत हो जाएंगे। स्थानीय चरों के साथ जुड़े स्टोरेज के जीवनकाल की शुरुआत और अंत के सापेक्ष आदेश पर समय से पहले काम किया जा सकता है।
इस कारण से, स्थानीय चर आमतौर पर "स्टैक" डेटा संरचना पर भंडारण के रूप में उत्पन्न होते हैं, क्योंकि एक स्टैक में संपत्ति होती है जिस पर पहली चीज को धक्का दिया जाता है, जो आखिरी चीज पॉप अप होती है।
यह ऐसा है जैसे होटल केवल कमरों को क्रमिक रूप से किराए पर लेने का फैसला करता है, और आप तब तक जांच नहीं कर सकते हैं, जब तक कि आपके द्वारा चेक किए गए कमरे से अधिक संख्या वाले सभी को नहीं।
तो चलो स्टैक के बारे में सोचते हैं। कई ऑपरेटिंग सिस्टम में आपको प्रति स्टैक एक स्टैक मिलता है और स्टैक एक निश्चित निश्चित आकार के लिए आवंटित किया जाता है। जब आप किसी विधि को कॉल करते हैं, तो स्टैक पर सामान धकेल दिया जाता है। यदि आप एक पॉइंटर को अपनी विधि से वापस लाते हैं, जैसा कि मूल पोस्टर यहाँ करता है, तो यह कुछ पूरी तरह से वैध मिलियन-बाइट मेमोरी ब्लॉक के बीच में एक पॉइंटर है। हमारे सादृश्य में, आप होटल से बाहर की जाँच करते हैं; जब आप ऐसा करते हैं, तो आप सबसे अधिक संख्या वाले कब्जे वाले कमरे से बाहर की जाँच करते हैं। यदि आपके बाद कोई और चेक नहीं करता है, और आप अवैध रूप से अपने कमरे में वापस जाते हैं, तो आपका सारा सामान इस विशेष होटल में रहने की गारंटी है ।
हम अस्थायी दुकानों के लिए ढेर का उपयोग करते हैं क्योंकि वे वास्तव में सस्ते और आसान हैं। स्थानीय लोगों के भंडारण के लिए स्टैक का उपयोग करने के लिए C ++ के कार्यान्वयन की आवश्यकता नहीं है; यह ढेर का उपयोग कर सकता है। यह नहीं है, क्योंकि यह कार्यक्रम को धीमा कर देगा।
सी ++ के कार्यान्वयन के लिए आवश्यक नहीं है कि आप कचरे को ढेर पर छोड़ दें, ताकि आप बाद में अवैध रूप से इसके लिए वापस आ सकें; यह कंपाइलर के लिए कोड उत्पन्न करने के लिए पूरी तरह से कानूनी है जो "रूम" में सब कुछ शून्य हो जाता है जिसे आपने अभी खाली किया था। यह फिर से नहीं है, क्योंकि यह महंगा होगा।
C ++ के कार्यान्वयन को यह सुनिश्चित करने की आवश्यकता नहीं है कि जब स्टैक तार्किक रूप से सिकुड़ता है, तो जो पते मान्य होते थे, वे अभी भी स्मृति में मैप किए जाते हैं। कार्यान्वयन को ऑपरेटिंग सिस्टम को बताने की अनुमति है "अब हम स्टैक के इस पृष्ठ का उपयोग कर रहे हैं। जब तक मैं अन्यथा नहीं कहता, तब तक एक अपवाद जारी करें जो प्रक्रिया को नष्ट कर देता है यदि कोई पहले से मान्य स्टैक पृष्ठ को छूता है"। फिर, कार्यान्वयन वास्तव में ऐसा नहीं करते हैं क्योंकि यह धीमा और अनावश्यक है।
इसके बजाय, कार्यान्वयन आपको गलतियाँ करने देते हैं और इससे दूर हो जाते हैं। सर्वाधिक समय। एक दिन तक कुछ सही मायने में भयानक हो जाता है और प्रक्रिया में विस्फोट हो जाता है।
यह समस्याग्रस्त है। बहुत सारे नियम हैं और उन्हें गलती से तोड़ना बहुत आसान है। मैं निश्चित रूप से कई बार है। और इससे भी बदतर, समस्या अक्सर सतहों की ही होती है जब स्मृति को भ्रष्टाचार के बाद नैनोसेकंड के अरबों भ्रष्ट होने का पता चलता है, जब यह पता लगाना बहुत मुश्किल होता है कि किसने इसे गड़बड़ किया।
अधिक मेमोरी-सुरक्षित भाषाएं आपकी शक्ति को सीमित करके इस समस्या को हल करती हैं। "सामान्य" C # में स्थानीय का पता लेने और इसे वापस करने या बाद में संग्रहीत करने का कोई तरीका नहीं है। आप स्थानीय का पता ले सकते हैं, लेकिन भाषा को चतुराई से डिज़ाइन किया गया है ताकि स्थानीय छोरों के जीवनकाल के बाद इसका उपयोग करना असंभव हो। एक स्थानीय का पता लेने और उसे वापस पारित करने के लिए, आपको एक विशेष "असुरक्षित" मोड में कंपाइलर को लगाना होगा, और अपने प्रोग्राम में "असुरक्षित" शब्द डालना होगा, इस तथ्य पर ध्यान देने के लिए कि आप शायद कर रहे हैं। कुछ खतरनाक जो नियमों को तोड़ सकता है।
आगे पढ़ने के लिए:
address of local variable ‘a’ returned
;Invalid write of size 4 [...] Address 0xbefd7114 is just below the stack ptr