मैं जानना चाहूंगा कि स्टैटिक मेमोरी एलोकेशन और डायनेमिक मेमोरी एलोकेशन में क्या अंतर है?
क्या आप इसे किसी भी उदाहरण के साथ समझा सकते हैं?
मैं जानना चाहूंगा कि स्टैटिक मेमोरी एलोकेशन और डायनेमिक मेमोरी एलोकेशन में क्या अंतर है?
क्या आप इसे किसी भी उदाहरण के साथ समझा सकते हैं?
जवाबों:
तीन प्रकार के आवंटन हैं - स्थैतिक, स्वचालित और गतिशील।
स्टेटिक आवंटन का मतलब है, कि प्रोग्राम शुरू होने पर आपके वेरिएबल्स के लिए मेमोरी आवंटित की जाती है। जब प्रोग्राम बनाया जाता है तो आकार निश्चित होता है। यह वैश्विक चरों पर लागू होता है, फ़ाइल स्कोप वैरिएबल, और वैरिएबल static
फंक्शन्स के साथ योग्य होते हैं।
स्वचालित मेमोरी आवंटन कार्यों के अंदर परिभाषित (गैर-स्थिर) चर के लिए होता है, और आमतौर पर स्टैक पर संग्रहीत किया जाता है (हालांकि सी मानक यह जनादेश नहीं देता है कि स्टैक का उपयोग किया जाता है)। आपको उनका उपयोग करके अतिरिक्त मेमोरी को आरक्षित करने की आवश्यकता नहीं है, लेकिन दूसरी ओर, इस मेमोरी के जीवनकाल पर भी सीमित नियंत्रण है। जैसे: किसी फंक्शन में ऑटोमैटिक वैरिएंट्स फंक्शन खत्म होने तक ही होते हैं।
void func() {
int i; /* `i` only exists during `func` */
}
डायनेमिक मेमोरी एलोकेशन थोड़ा अलग है। अब आप इन मेमोरी स्थानों के सटीक आकार और जीवनकाल को नियंत्रित करते हैं। यदि आप इसे खाली नहीं करते हैं, तो आप मेमोरी लीक में चले जाएंगे, जिससे आपका एप्लिकेशन क्रैश हो सकता है, क्योंकि किसी समय, सिस्टम अधिक मेमोरी आवंटित नहीं कर सकता है।
int* func() {
int* mem = malloc(1024);
return mem;
}
int* mem = func(); /* still accessible */
ऊपरी उदाहरण में, आवंटित स्मृति अभी भी वैध और सुलभ है, भले ही फ़ंक्शन समाप्त हो गया हो। जब आप स्मृति के साथ किया जाता है, तो आपको इसे मुक्त करना होगा:
free(mem);
यह एक मानक साक्षात्कार प्रश्न है:
स्मृति रनटाइम का उपयोग कर आवंटित किया गया है calloc()
, malloc()
और दोस्तों। इसे कभी-कभी 'हीप' मेमोरी के रूप में भी जाना जाता है, हालांकि इसका ढेर डेटा-संरचना रेफ के साथ कोई लेना-देना नहीं है ।
int * a = malloc(sizeof(int));
हीप मेमोरी तब तक लगातार बनी रहती है जब तक free()
कि उसे कहा नहीं जाता दूसरे शब्दों में, आप चर के जीवनकाल को नियंत्रित करते हैं।
यह वह है जिसे आमतौर पर 'स्टैक' मेमोरी के रूप में जाना जाता है, और जब आप एक नया स्कोप दर्ज करते हैं तो आवंटित किया जाता है (आमतौर पर जब एक नया फ़ंक्शन कॉल स्टैक पर धकेल दिया जाता है)। एक बार जब आप दायरे से बाहर निकल जाते हैं, तो स्वचालित मेमोरी एड्रेस के मान अपरिभाषित हो जाते हैं, और उन्हें एक्सेस करना एक त्रुटि है ।
int a = 43;
ध्यान दें कि कार्यक्षेत्र का मतलब जरूरी नहीं है। स्कोप एक फ़ंक्शन के भीतर घोंसला कर सकते हैं, और चर केवल उस खंड के दायरे में होगा जिसमें इसे घोषित किया गया था। ध्यान दें कि जहां यह मेमोरी आवंटित की गई है, वह निर्दिष्ट नहीं है। (एक फलक प्रणाली पर यह ढेर पर होगा, या अनुकूलन के लिए रजिस्टर होगा)
संकलन समय * पर आबंटित किया जाता है , और स्थिर स्मृति में एक चर का जीवनकाल कार्यक्रम का जीवनकाल होता है ।
C में, स्थिर मेमोरी को static
कीवर्ड का उपयोग करके आवंटित किया जा सकता है । दायरा केवल संकलन इकाई है।
जब extern
कीवर्ड माना जाता है तो चीजें अधिक दिलचस्प हो जाती हैं । जब एक extern
चर को परिभाषित किया जाता है तो संकलक इसके लिए मेमोरी आवंटित करता है। जब एक extern
चर घोषित किया जाता है , तो संकलक के लिए आवश्यक है कि चर को अन्यत्र परिभाषित किया जाए। extern
चरों को घोषित / परिभाषित करने में विफलता के कारण लिंकिंग समस्याएं होंगी, जबकि static
चरों को घोषित / परिभाषित करने में विफलता संकलन समस्याओं का कारण होगी।
फ़ाइल स्कोप में, स्थिर कीवर्ड वैकल्पिक है (फ़ंक्शन के बाहर):
int a = 32;
लेकिन फंक्शन स्कोप में नहीं (फंक्शन के अंदर):
static int a = 32;
तकनीकी रूप से, extern
और static
सी में चर के दो अलग-अलग वर्ग हैं।
extern int a; /* Declaration */
int a; /* Definition */
यह कहना कुछ भ्रामक है कि स्थिर मेमोरी को संकलन समय पर आवंटित किया जाता है, खासकर अगर हम यह विचार करना शुरू कर दें कि संकलन मशीन और होस्ट मशीन समान नहीं हो सकती है या समान आर्किटेक्चर पर भी नहीं हो सकती है।
यह सोचना बेहतर होगा कि स्थिर मेमोरी का आवंटन संकलक द्वारा संकलित किया जाता है बजाय संकलन समय पर आवंटित किए ।
उदाहरण के लिए संकलक data
बाइनरी में एक बड़ा खंड बना सकता है और जब प्रोग्राम को मेमोरी में लोड किया जाता है, तो उसके भीतर का पताdata
कार्यक्रम का खंड आवंटित स्मृति के स्थान के रूप में उपयोग किया जाएगा। यह संकलित बाइनरी को बहुत बड़ा बनाने का चिह्नित नुकसान है अगर बहुत अधिक स्थिर मेमोरी का उपयोग करता है। कोड की आधा दर्जन से कम लाइनों से उत्पन्न एक बहु-गीगाबाइट बाइनरी लिखना संभव है। एक अन्य विकल्प कंपाइलर के लिए इनिशियल कोड को इंजेक्ट करना है जो प्रोग्राम निष्पादित होने से पहले किसी अन्य तरीके से मेमोरी आवंटित करेगा। यह कोड लक्ष्य प्लेटफ़ॉर्म और OS के अनुसार अलग-अलग होगा। व्यवहार में, आधुनिक संकलक यह निर्धारित करने के लिए कि इनमें से किस विकल्प का उपयोग करने के लिए heuristics का उपयोग करते हैं। आप एक छोटा सी प्रोग्राम लिखकर इसे स्वयं आज़मा सकते हैं जो 10k, 1m, 10m, 100m, 1G या 10G आइटमों के बड़े स्थिर सरणी को आवंटित करता है। कई संकलक के लिए, द्विआधारी आकार सरणी के आकार के साथ रैखिक रूप से बढ़ता रहेगा, और एक निश्चित बिंदु से अतीत होगा,
अंतिम मेमोरी क्लास 'रजिस्टर' चर हैं। जैसा कि अपेक्षित था, रजिस्टर चर को सीपीयू के रजिस्टर पर आवंटित किया जाना चाहिए, लेकिन निर्णय वास्तव में संकलक के लिए छोड़ दिया गया है। आप पता-का उपयोग करके एक संदर्भ में एक रजिस्टर चर नहीं बदल सकते हैं।
register int meaning = 42;
printf("%p\n",&meaning); /* this is wrong and will fail at compile time. */
अधिकांश आधुनिक संकलक आपसे बेहतर हैं कि कौन से चर को रजिस्टर में रखा जाना चाहिए :)
int * a = malloc(sizeof(*a));
इसके बजाय सुझाव देना चाहूंगा कि किस प्रकार के दोहराव से बचें a
। यह चीजों को बहुत आसान बना देता है यदि कभी a
परिवर्तन के प्रकार ।
स्टैटिक मेमोरी एलोकेशन: कंपाइलर एक घोषित चर के लिए आवश्यक मेमोरी स्पेस आवंटित करता है। ऑपरेटर के पते का उपयोग करके, आरक्षित पता प्राप्त किया जाता है और यह पता एक पॉइंटर चर को सौंपा जा सकता है। तब घोषित किए गए अधिकांश वेरिएबल में स्थिर मेमोरी होती है, यह पॉइंटर वैरिएबल को पॉइंटर मान असाइन करने का तरीका स्टैटिक मेमोरी एलोकेशन के रूप में जाना जाता है। संकलन समय के दौरान स्मृति को सौंपा गया है।
डायनेमिक मेमोरी एलोकेशन: यह मेमोरी को गतिशील रूप से प्राप्त करने के लिए मॉलॉक () या कॉलोक () जैसे फ़ंक्शंस का उपयोग करता है। यदि इन फ़ंक्शंस का उपयोग मेमोरी को गतिशील रूप से प्राप्त करने के लिए किया जाता है और इन फ़ंक्शंस द्वारा दिए गए मान पॉइंटर वैरिएबल को दिए जाते हैं, तो ऐसे असाइनमेंट्स को डायनामिक मेमोरी के लिए जाना जाता है। आबंटन समय के दौरान आवंटन।
स्थैतिक मेमोरी आवंटन:
गतिशील मेमोरी आवंटन:
स्टेटिक मेमोरी एलोकेशन और डायनामिक मेमोरी एलोकेशन के बीच अंतर
कार्यक्रम के निष्पादन (संकलन के दौरान) शुरू होने से पहले मेमोरी आवंटित की जाती है।
कार्यक्रम के निष्पादन के दौरान मेमोरी आवंटित की जाती है।
निष्पादन के दौरान कोई मेमोरी आवंटन या डील्लोकेशन क्रिया नहीं की जाती है।
मेमोरी बाइंडिंग निष्पादन के दौरान स्थापित और नष्ट हो जाते हैं।
चर स्थायी रूप से आवंटित किए जाते हैं।
केवल तभी आवंटित किया जाता है जब प्रोग्राम यूनिट सक्रिय हो।
ढेर और ढेर का उपयोग कर लागू किया गया।
डेटा सेगमेंट का उपयोग करके कार्यान्वित किया गया।
चर तक पहुँचने के लिए पॉइंटर की आवश्यकता होती है।
डायनामिक रूप से आवंटित पॉइंटर्स की कोई आवश्यकता नहीं है।
गतिशील की तुलना में तेज़ निष्पादन।
स्थिर की तुलना में धीमी निष्पादन।
अधिक मेमोरी स्पेस की आवश्यकता है।
कम मेमोरी स्थान की आवश्यकता।
संकलन समय के दौरान निष्पादन पीएफ कार्यक्रम से पहले स्टैटिक मेमोरी आवंटन को मेमोरी आवंटित की जाती है। रन टाइम के दौरान प्रोग्राम के निष्पादन के दौरान डायनामिक मेमोरी एलोकेशन को अलोकेटेड मेमोरी कहा जाता है।