2013-03-06 4 views
7

ब्लॉक स्कोप बनाम मॉलोक का उपयोग कर स्थिर कीवर्ड का क्या फायदा है?स्टेटिक बनाम मॉलोक

उदाहरण के लिए:

समारोह एक:

f() { 
    static int x = 7; 
} 

समारोह बी:

f() { 
    int *x = malloc(sizeof(int)); 
    if (x != NULL) 
     *x = 7; 
} 

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

+0

आपके फंक्शन ए में, [स्थैतिक चर ढेर में संग्रहीत नहीं हैं] (http://stackoverflow.com/questions/93039/where-are-static-variables-stored-in-cc) .. – Krishnabhadra

+0

जिस तरह से आप क्या यह एक स्मृति रिसाव है - प्रत्येक बार जब आप f() कहते हैं - मुझे लगता है कि इससे बचने का एक कारण है! – John3136

+0

वे पूरी तरह से एक ही उद्देश्य के लिए नहीं हैं। फंक्शन ए में, पूर्णांक 7 स्थिर क्षेत्र में संग्रहीत होता है (संकलन के दौरान आवंटित, HEAP पर नहीं!)। इसे केवल एक बार आवंटित किया जाता है, जबकि फ़ंक्शन बी में, आप func बी को कॉल करने के बाद एक पूर्णांक आवंटित करते हैं। –

उत्तर

6

दोनों कार्यक्रमों एक integer 7 कि ढेर

नहीं, वे नहीं करते पर संग्रहीत है बनाएँ।
static स्थैतिक भंडारण अवधि के साथ एक वस्तु बनाता है जो कार्यक्रम के पूरे जीवनकाल में जीवंत रहता है। जबकि गतिशील रूप से आवंटित ऑब्जेक्ट (malloc द्वारा निर्मित) free द्वारा स्पष्ट रूप से हटाए जाने तक स्मृति में बना रहता है। दोनों अलग कार्यक्षमता प्रदान करते हैं। static गतिशील रूप से आवंटित ऑब्जेक्ट नहीं होने पर ऑब्जेक्ट की स्थिति को फ़ंक्शन कॉल के भीतर बनाए रखता है।

आप किस प्रकार की स्थितियों में एक विधि का उपयोग कर सकते हैं?

आप static का उपयोग करके ऐसी वस्तु कार्यक्रम के जीवन भर जिंदा हो सकता है और समारोह कॉल के अंतर्गत अपने राज्य बनाए रखना चाहते हैं। यदि आप एक बहुप्रचारित वातावरण में काम कर रहे हैं तो static ऑब्जेक्ट सभी थ्रेड के लिए साझा किया जाएगा और इसलिए सिंक्रनाइज़ेशन की आवश्यकता होगी।

आप malloc का उपयोग जब आप स्पष्ट रूप से object.for जैसे के जीवनकाल को नियंत्रित करना चाहते:। यकीन है कि वस्तु काफी लंबे समय तक समारोह के फोन करने वाले समारोह कॉल के बाद उसके द्वारा पहुंच रहता बनाना (एक स्वत:/स्थानीय वस्तु पुनः आवंटित की जाती हो जाएगा एक बार कार्य के { } का दायरा समाप्त होता है)। जब तक कॉलर स्पष्ट रूप से free पर कॉल नहीं करता है तब तक आवंटित स्मृति लीक हो जाती है जब तक कि ओएस प्रोग्राम से बाहर निकलने पर इसे पुनः प्राप्त न करे।

+0

क्या आप मॉलोक का अधिक उपयोग नहीं करना चाहते हैं क्योंकि इससे आपको उस स्मृति को मुक्त करने में सक्षम होने की लचीलापन मिलती है जब आपको आवश्यकता होती है? या ऐसे कई उदाहरण हैं जहां स्थायी रूप से बने रहने के लिए आपको चर की आवश्यकता होगी? – CowZow

+0

@CowZow: यह उस कार्यक्षमता पर अधिक निर्भर करता है जिसे आप प्राप्त करना चाहते हैं, उदाहरण के लिए: कभी-कभी आपको पूरे कार्यक्रम के जीवनकाल के दौरान कुछ ट्रैक रखने के लिए काउंटर की आवश्यकता होती है, 'स्थिर' प्राकृतिक विकल्प होगा। साथ ही, यह ध्यान रखना महत्वपूर्ण है कि गतिशील स्मृति उपयोग में उपयोगिता त्रुटियों के अधिक प्रवण होने के अलावा थोड़ा प्रदर्शन ओवरहेड है। तो पाठ्यक्रम के लिए घोड़े नियम है। –

0

फंक्शन ए में, आप स्थिर भंडारण अवधि के साथ x आवंटित कर रहे हैं, जिसका आमतौर पर इसका मतलब है कि यह ढेर नहीं है (अधिकांश लोग किस प्रकार पहचानते हैं) ढेर। इसके बजाय, यह केवल स्मृति है जो आपके कार्यक्रम के पूरे समय मौजूद होने की गारंटी है।

फ़ंक्शन बी में, जब भी आप फ़ंक्शन में प्रवेश करते हैं, तब तक आप स्टोरेज आवंटित कर रहे हैं, और फिर (जब तक कोई free नहीं दिखाया गया है) उस स्मृति को लीक कर रहा है।

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

0

ढेर वी भूल जाओ। ढेर। यह सबसे महत्वपूर्ण बात नहीं है जो यहां जा रही है।

कभी कभी staticगुंजाइश को संशोधित करता है और कभी कभी यह जीवन संशोधित करता है। प्रोटोटाइप उदाहरण:

void int foo() { 
    static int count = 0; 
    return count++; 
} 

कोशिश भी कई विभिन्न कार्यों या फाइलों से शायद बार-बार इस बुला, और आप देखेंगे कि count बढ़ती रहती है, क्योंकि इस मामले static में चर एक जीवन भर के पूरे के बराबर देता है कार्यक्रम का निष्पादन

0

अगर मैं सही ढंग से इस समझ रहा हूँ, दोनों कार्यक्रमों एक पूर्णांक 7 कि ढेर

नहीं है, स्थैतिक चर created in Data or BSS segment हैं पर संग्रहीत है बनाते हैं, और वे इस कार्यक्रम के जीवन भर जीवन है । जब आप malloc() का उपयोग कर alloc, स्मृति ढेर में आवंटित किया जाता है, और वे स्पष्ट रूप से free() कॉल का उपयोग कर मुक्त कर दिया जाना चाहिए।

आप किस प्रकार की स्थितियों में एक विधि का उपयोग कर सकते हैं?

ठीक है, आप पहली विधि का उपयोग करते हैं, जब आप एक ही चर के एकाधिक आमंत्रण के लिए एक ही चर तक पहुंच चाहते हैं। यानी, आपके उदाहरण में, एक्स केवल एक बार आरंभ किया जाएगा, और जब आप दूसरी बार विधि को कॉल करेंगे, तो उसी x चर का उपयोग किया जाता है।

दूसरी विधि का उपयोग किया जा सकता है, जब आप फ़ंक्शन के एकाधिक आमंत्रण के लिए चर साझा नहीं करना चाहते हैं, ताकि यह फ़ंक्शन दूसरी बार कॉल किया जा सके, x malloc एड फिर से है। आपको हर बार एक्स मुक्त करना होगा।

आपके पास कॉल f() 2 बार से अंतर देख सकते हैं परिणाम हो जाएगा अलग

0

पढ़ें http://www.teigfam.net/oyvind/pub/notes/09_ANSI_C_static_vs_malloc.html

f()

... 
f(); 
f(); 
... 

f(){ 
    static int x = 7; 
    printf("x is : %d", x++); 
} 

f(){ 
    int *x = malloc(sizeof(int)); 
    if (x != NULL) 
     *x = 7; 
    printf("x is : %d", (*x)++); 
    free(x); //never forget this, 
} 

के प्रत्येक प्रकार के लिए, स्थैतिक चर मुख्य तैयार होने से पहले () और कार्यक्रम चलाने के बाद स्मृति आवंटित करने की आवश्यकता नहीं है।

0

सबसे पहली बात, स्थिर एक भंडारण वर्ग, और malloc() एक एपीआई, जो ढेर पर स्मृति को आबंटित करने brk() सिस्टम कॉल से चलाता है।

अगर मैं सही ढंग से इस समझ रहा हूँ, दोनों कार्यक्रमों एक पूर्णांक 7 कि ढेर पर संग्रहीत किया जाता है बनाने के?

नहीं। स्टेटिक चर प्रोग्राम के आवंटित स्मृति के डेटा अनुभाग में संग्रहीत हैं। हालांकि अगर एक स्थिर चर समाप्त होता है की गुंजाइश, यह अभी भी इसके दायरे के बाहर पहुँचा जा सकता है, इस का संकेत हो सकता है कि, डेटा खंड की सामग्री, एक जीवन दायरे से स्वतंत्र है।

आप किस प्रकार की स्थितियों में एक विधि का उपयोग कर सकते हैं?

आप अधिक नियंत्रण चाहते हैं किसी दिए गए दायरे के भीतर, अपनी स्मृति उपयोग malloc()/free() से अधिक, है, और सरल (और अधिक क्लीनर) जिस तरह से स्थिर उपयोग करने के लिए है।

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

पर निर्भर करता है एक और कारण मैं स्थिर सुझाव देने के बारे में सोच सकता हूं कि स्थिर चर डिफ़ॉल्ट रूप से शून्य से प्रारंभ होते हैं, तो चिंता करने के लिए एक और कम बात है।

0

समझने के लिए नीचे बताएं कि कैसे स्थिर कार्य करता है। आम तौर पर हम परिवर्तनीय या फ़ंक्शन के दायरे को परिभाषित करने के लिए स्थिर कीवर्ड का उपयोग करते हैं। जैसे स्थैतिक के रूप में परिभाषित एक चर को फ़ंक्शन के भीतर प्रतिबंधित किया जाएगा और इसके मूल्य को खुदरा कर दिया जाएगा।

लेकिन जैसा कि आप नीचे दिए गए नमूना कार्यक्रम में दिखाए गए हैं यदि आप स्थिर चर के संदर्भ को किसी अन्य फ़ंक्शन पर पास करते हैं तो भी आप किसी भी अन्य फ़ंक्शन से एक ही चर को अपडेट कर सकते हैं।

लेकिन कार्यक्रम समाप्त होने पर स्थिर चर मर जाता है, इसका मतलब है कि स्मृति मुक्त हो जाएगी।

#include <stdio.h> 

void f2(int *j) 
{ 
    (*j)++; 
    printf("%d\n", *j); 
} 

void f1() 
{ 
    static int i = 10; 
    printf("%d\n", i); 
    f2(&i); 
    printf("%d\n", i); 
} 

int main() 
{ 
    f1();  
    return 0; 
} 

लेकिन malloc() के मामले में, स्मृति कार्यक्रम की समाप्ति पर मुक्त नहीं किया जाएगा जब तक और तक प्रोग्रामर कार्यक्रम की समाप्ति से पहले मुक्त() का उपयोग कर स्मृति को मुक्त कराने का ख्याल रखता है।

इस तरह आप महसूस करेंगे कि malloc() का उपयोग करके हम परिवर्तनीय जीवनकाल पर नियंत्रण रख सकते हैं लेकिन सावधान रहें ... जब आप गतिशील स्मृति आवंटन चुनते हैं तो आपको स्मृति आवंटित करने और मुक्त करने में बहुत सटीक होना चाहिए। यदि आप मेमोरी और प्रोग्राम को मुक्त करना भूल जाते हैं तो ढेर के उस भाग को अन्य प्रक्रिया द्वारा स्मृति आवंटित करने के लिए उपयोग नहीं किया जा सकता है। यह संभवतः वास्तविक दुनिया में स्मृति की भुखमरी का कारण बन जाएगा और गणना को धीमा कर देगा। ऐसी स्थिति से बाहर निकलने के लिए आपको सिस्टम को मैन्युअल रूप से रीबूट करना होगा।

संबंधित मुद्दे