c - स्थैतिक सरणियों को मुक्त करने की आवश्यकता क्यों नहीं है?




scope static (4)

मैं सोच रहा हूं कि स्थिर सरणियों को मुक्त करने की आवश्यकता क्यों नहीं है? मुझे पता है कि जब एक गतिशील सरणी पैदा करना

int *p;
p = malloc(10*sizeof(int));

हमें आबंटित मेमोरी को उपयोग कर मुक्त करना होगा:

free(p);

और किसी फ़ंक्शन में एक स्थिर सरणी के लिए, कहा जाता समारोह किया जाता है जब स्थिर सरणी स्वचालित रूप से मुक्त हो जाएगा।

मुझे जो समझ में नहीं आता है: जब इस तरह एक फ़ंक्शन का उपयोग करके एक स्थिर सरणी लौटते हैं:

int *subFunc(){
    static int a[5] = {1,2,3,4,5};
    return a;
}

int main(){
    int *p;
    p = subFunc();
}

अगर स्थिर सरणी निष्पादन को पूरा करने के बाद स्वचालित रूप से मुक्त हो जाती है, तो फिर हम स्थिर अवस्था के मूल्यों को सही ढंग से कैसे उपयोग कर सकते हैं?


और एक उप समारोह में एक स्थिर सरणी के लिए, जब स्थिर उप समारोह किया जाता है तो स्थिर सरणी स्वचालित रूप से मुक्त हो जाएगी।

वह सत्य नहीं है। जब आप फ़ंक्शन दर्ज करते हैं, तो स्टेटिक एरेज़ नहीं बनाए जाते हैं, और जब आप इसे छोड़ते हैं तो वे नष्ट नहीं होते हैं।

एक स्थिर वैरिएबल, और इसके अंदर के डेटा, वास्तव में एक वैश्विक चर की तरह बहुत कुछ है ! समारोह में स्थानीय है जो केवल एक चीज़ है नाम । (आप लोगों को चर की "गुंजाइश" के बारे में बात करेंगे - इसका अर्थ है "मैं इसका इस्तेमाल करने के लिए कहां नाम का उपयोग कर सकता हूं।")

इसलिए जब आप एक स्थिर सरणी के जीवन के बारे में सोच रहे हैं, तो आप मानसिक रूप से प्रतिस्थापित कर सकते हैं:

int *subFunc(){
    static int a[5] = {1,2,3,4,5};
    return a;
}

साथ में

int ONLY_USE_ME_INSIDE_SUBFUNC__a[5] = {1,2,3,4,5};  /* global variable */

int *subFunc(){
    int * a = ONLY_USE_ME_INSIDE_SUBFUNC__a;  /* a is the same as the global */
    return a;
}

और फिर अपने कार्यक्रम में कोई भी बहाना नहीं कर सकता जो उस वैश्विक चर को छू सकता है।


मैं सोच रहा हूं कि स्थिर सरणियों को मुक्त करने की आवश्यकता क्यों नहीं है?

  1. मेमोरी प्रबंधन फ़ंक्शन (मॉलोक, कॉलोक) द्वारा आवंटित नहीं किया जा रहा है, जैसे कि int a[5] आवश्यकता को स्पष्ट रूप से मुक्त करने के लिए ध्यान नहीं दिया जाएगा।

  2. स्थैतिक चर जैसे स्थैतिक चर, static int a[5] स्थानीय क्षेत्र के भीतर सुलभ (वे स्थानीय फ़ंक्शन के बाद के कॉल के बीच अपने मूल्यों को बनाए रखती है) के लिए उपलब्ध कराते हैं। वे इस प्रयोजन के लिए समय को संकलित करने पर तैयार किए जाते हैं, उनके पास एक कार्यक्रम का जीवनकाल है, इसलिए यह उन्हें मुक्त करने के लिए एक तार्किक विचार नहीं होगा, भले ही यह संभव हो, जो नहीं है

  3. बाकी सब कुछ अन्य उत्तर में स्पष्ट रूप से समझाया जा रहा है


अगर स्थिर सरणी निष्पादन को पूरा करने के बाद स्वचालित रूप से मुक्त हो जाती है, तो फिर हम स्थिर अवस्था के मूल्यों को सही ढंग से कैसे उपयोग कर सकते हैं?

नहीं, यह ऐसा नहीं है static चर को main() शुरू करने से पहले आरंभीकृत किया जाता है और इसका जीवनकाल कार्यक्रम का संपूर्ण निष्पादन होता है। इसलिए, वे कार्यों से return सकते हैं (जिसमें वे परिभाषित हैं) और अभी भी उपयोग किया जा सकता है। वे स्थानीय (कार्य करने के लिए) नहीं हैं, जो फ़ंक्शन पूर्ण होने पर जीवनकाल से बाहर निकल जाता है।

संबंधित, C11 से अध्याय, अध्याय §6.2.4

एक ऑब्जेक्ट जिसका पहचानकर्ता स्टोरेज-श्रेणी विनिर्देशक _Thread_local बिना घोषित किया गया है, और या तो बाहरी या आंतरिक लिंकेज के साथ या स्टोरेज-श्रेणी विनिर्देशक static , स्थिर संग्रहण अवधि है। इसका जीवनकाल कार्यक्रम का पूरा निष्पादन होता है और इसकी संचयित मूल्य केवल एक बार शुरू किया जाता है, कार्यक्रम स्टार्टअप से पहले।

फ़ंक्शन के अंदर एक static चर के दायरे के बारे में, हाँ, यह फ़ंक्शन के लिए ही सीमित है, जैसा कि अध्याय §6.2.1 में वर्णित है,

[...] यदि एक घोषणा परिभाषितकर्ता घोषित करता है या किसी फ़ंक्शन परिभाषा में पैरामीटर घोषणाओं की सूची के भीतर पहचानकर्ता की घोषणा करता है, तो पहचानकर्ता ब्लॉक ब्लॉक है, जो संबंधित ब्लॉक के अंत में समाप्त होता है। [...]

इसका मतलब है, जाहिर है, आप a बाहरी subFunc() बाहर सरणी का उपयोग नहीं कर सकते, क्योंकि subFunc() बाहर दिखाई नहीं दे रहा है

हालांकि, जब आप सरणी वापस लौटते हैं (सरणी को लौटाने के कारण सरणी के पहले तत्व के सूचक को क्षय का कारण बनता है, FWIW), क्योंकि static सरणी का जीवनकाल प्रोग्राम का संपूर्ण निष्पादन है, लौटा संकेतक (निश्चित रूप से, सीमा के भीतर) पूरी तरह से मान्य है और कानूनी है।


फ़ंक्शन के अंदर Static variables , आमतौर पर इसके लिए कई कॉलों पर फ़ंक्शन के दायरे में कुछ डेटा बनाए रखने के लिए उपयोग किया जाता था । वे मुख्य () से पहले आरंभ किए जाते हैं और उनका जीवनकाल कार्यक्रम के पूरे निष्पादन के रूप में होता है। इसलिए, यदि यह समारोह से बाहर निकलने के बाद उन्हें रिहा कर दिया गया तो इसका मतलब यह नहीं होगा। यदि आप उन्हें नि: शुल्क निकालते हैं, तो आप अगली बार जब आप फ़ंक्शन कॉल करेंगे, तो वे क्रैश करेंगे क्योंकि उनका संदर्भ नहीं दिया जाएगा।





lifetime