2012-03-28 11 views
11

उदाहरण के लिए, मैं स्मृति के दो टुकड़े malloc की जरूरत है, तो:मजबूत सी प्रोग्राम लिखने के लिए, आप बहुत से अलग मुक्त() संयोजनों से कैसे बचते हैं?

void *a = malloc (1); 

if (!a) 
    return -1; 

void *b = malloc (1); 

if (!b) 
{ 
    free (a); 
    return -1; 
} 

सूचना यदि दूसरा malloc विफल रहता है, मैं मुक्त करने के लिए "एक" पहले की है। समस्या यह है, यह अगर वहाँ कई ऐसे malloc और त्रुटि जाँच की जब तक कि मैं कुख्यात "गोटो" खंड का उपयोग करें और ध्यान से मुक्त का का क्रम निर्धारित लेबल के साथ कर रहे हैं, बहुत गंदा हो सकता है:

void *a = malloc (1); 

if (!a) 
    goto X; 

void *b = malloc (1); 

if (!b) 
    goto Y; 

return 0; //normal exit 

Y: 
    free (a); 
X: 
    return -1; 

क्या आपके पास इस स्थिति के लिए कोई बेहतर समाधान? अग्रिम में धन्यवाद।

+0

+1 एक बार मैं भी एक ही समस्या का सामना करना पड़ा लेकिन "गन्दा कोड" के साथ काम पूरा कर लिया है .. !! –

उत्तर

18

हम इस तरह कार्य करें:

void *a = NULL; 
void *b = NULL; 
void *c = NULL; 
a = malloc(1); 
if (!a) goto errorExit; 
b = malloc(1); 
if (!b) goto errorExit; 
c = malloc(1); 
if (!b) goto errorExit; 

return 0; 
errorExit: 
//free a null pointer is safe. 
free(a); 
free(b); 
free(c); 
return -1; 
+4

+1 यह इंगित करने के लिए कि नि: शुल्क पॉइंटर्स स्वीकार करता है। मुझे नहीं पता था कि यह मामला था। – Leo

+0

भले ही यह नहीं किया गया (या यदि आपको कुछ अन्य संसाधनों को मुक्त करने की आवश्यकता है जहां संबंधित सफाई कार्य ऐसा नहीं करता है), तो आप हमेशा 'if (a) मुक्त (ए);' और इसी तरह से कर सकते हैं। –

13

मेरी राय में गोटो का उपयोग करना एक बुरी बात नहीं है। संसाधन सफाई के लिए इसका उपयोग करना इसके लिए सही है।

लिनक्स कर्नेल के रूप में प्रसिद्ध स्रोत कोड तकनीक का उपयोग करता है।

बस पीछे जाने के लिए गोटो का उपयोग न करें। इससे आपदा और भ्रम पैदा होता है। केवल मेरी सिफारिश है आगे बढ़ो।

+4

न केवल लिनक्स कर्नेल यह करता है, बल्कि फ्रीबीएसडी भी करता है। पूरी तरह से सहमत हैं कि यह सामान्य अभ्यास है। – arrowd

+0

मैंने अभी भी वही लंबे समय पहले किया था जब अभी भी शुद्ध सी का उपयोग कर रहा है (सी ++ का उपयोग करके) मैं स्मार्ट पॉइंटर्स का उपयोग करता हूं। – Patrick

+1

इसके अलावा; मुफ्त नहीं है (एनयूएलएल) नो-ऑप? मतलब यह है कि सब कुछ मुक्त करने में कोई समस्या नहीं है? – Alxandr

3

जैसा कि पहले उल्लेख किया गया था Zan Lynx गोटो स्टेटमेंट का उपयोग करें।

आप आगे के उपयोग के लिए स्मृति के बड़े हिस्से को भी आवंटित कर सकते हैं।

या आप memory pool जैसे कुछ विकसित करने के लिए अपना समय निवेश कर सकते हैं।

3

या ऐसा करें।

void *a,*b; 
char * p = malloc(2); 
if (!p) return -1; 
a = p; 
b = p+1; 
2

मुझे लगता है कि OOP तकनीक आप इस समस्या के लिए एक अच्छा और साफ समाधान दे सकता है:

typedef struct { 
    void *a; 
    void *b; 
} MyObj; 

void delete_MyObj(MyObj* obj) 
{ 
    if (obj) { 
     if (obj->a) 
      free(obj->a); 
     if (obj->b) 
      free(obj->b); 
     free(obj); 
    } 
} 

MyObj* new_MyObj() 
{ 
    MyObj* obj = (MyObj*)malloc(sizeof(MyObj)); 
    if (!obj) return NULL; 
    memset(obj, 0, sizeof(MyObj)); 

    obj->a = malloc(1); 
    obj->b = malloc(1); 

    if (!obj->a || !obj->b) { 
     delete_MyObj(obj); 
     return 0; 
    } 

    return obj; 
} 

int main() 
{ 
    MyObj* obj = new_MyObj(); 
    if (obj) { 
     /* use obj */ 
     delete_MyObj(obj); 
    } 
} 
+0

यदि आपको एकाधिक ऑब्जेक्ट्स की आवश्यकता है तो क्या होगा? फिर आप वापस आ गए हैं जहां आपने शुरू किया था। – Austin

2

वास्तव में अपने goto कोड के साथ गलत कुछ भी नहीं है आईएमओ (मैं अधिक वर्बोज लेबल का उपयोग करता हूं)।

हालांकि इस मामले में, goto कथन जो आपने लिखा है, उसी तरह की संरचना बनाते हैं जो if s को उलट देता है।

है यही कारण है कि, एक सशर्त आगे goto है कि किसी भी गुंजाइश नहीं छोड़ता नहीं else के साथ एक if बयान के रूप में ठीक उसी करता है। अंतर यह है कि gotoहोता है गुंजाइश छोड़ने के लिए नहीं, जबकि if बाधा छोड़ने के लिए नहीं है। यही कारण है कि if आमतौर पर पढ़ने के लिए आसान है: पाठक के सामने अधिक सुराग है।

void *a = malloc (1); 
if (a) { 
    void *b = malloc (1); 
    if (b) { 
     return 0; //normal exit 
    } 
    free(a); 
} 
return -1; 

स्तरों के एक जोड़े यह ठीक है के लिए, हालांकि बहुत दूर ले जाया आप खरोज की भी कई स्तरों के साथ "तीर कोड" मिलता है। यह पूरी तरह से अलग कारणों से अपठनीय हो जाता है।

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