2010-06-06 5 views
11

मेमोरी लीक से बचने के तरीके मेरे अनुप्रयोगों में मेमोरी लीक से बचने के लिए मैं कुछ युक्तियाँ क्या उपयोग कर सकता हूं? मेरी वर्तमान परियोजना में मैं एक उपकरण "INSURE ++" का उपयोग करता हूं जो स्मृति रिसाव पाता है और रिपोर्ट उत्पन्न करता है।सी/सी ++

उपकरण के अलावा मेमोरी लीक की पहचान करने और इसे दूर करने के लिए कोई विधि है।

+10

क्या आप सी, या सी ++ का उपयोग कर रहे हैं? उपलब्ध समाधान दो भाषाओं के लिए काफी अलग हैं। –

+0

मैं सी का उपयोग कर रहा हूं। क्या आप सी और सी ++ – Ankur

+7

@ अंकुर दोनों के लिए एक प्रस्ताव प्रदान कर सकते हैं: ठीक है एक उत्तर जो सी के लिए समझ में आता है सी ++ और इसके विपरीत के लिए समझ में नहीं आता है। मेमोरी प्रबंधन बिट्स में से एक है जो सी ++ में बदल जाता है। –

उत्तर

9

ऐसा करने के तीन मुख्य तरीके हैं।

पहला पहले स्थान पर मेमोरी लीक नहीं बना रहा है। रक्षात्मक प्रोग्रामिंग तकनीक यहां अमूल्य हैं। इस समस्या के सारांश के लिए excellent presentation देखें, या Secure C Coding में प्रासंगिक अध्याय देखें। मैं सी ++ से सी से अधिक परिचित हूं, लेकिन मैं समझता हूं कि सी ++ के smart pointers यहां उपयोगी हैं।

एक दूसरा दृष्टिकोण स्थैतिक विश्लेषण, जो आपके स्रोत-कोड में त्रुटियों का पता लगाने का प्रयास करता है। इस श्रेणी में मूल उपकरण लिंट है, जो अब दुखद पुराना है। जहां तक ​​मुझे पता है, सर्वोत्तम उपकरण coverty जैसे वाणिज्यिक हैं। हालांकि, कुछ free tools do exist

तीसरा दृष्टिकोण रनटाइम पर मेमोरी लीक का पता लगाने के लिए है, जैसे INSURE ++ करता है। Valgrind यहां उत्कृष्ट है और अत्यधिक अनुशंसित है। यह आपके द्वारा पहले से पेश की गई बग को पकड़ने में सहायता कर सकता है। यह विशेष रूप से सहायक होता है यदि आपके पास एक परीक्षण सूट है जिसमें अच्छा कोड कवरेज है।

0

से बचने या पहचानने के लिए? इससे बचने के लिए, पहले पहचानें और समझने की कोशिश करें कि क्यों और क्यों ... एक और तरीका जीसी लाइब्रेरी का उपयोग हो सकता है, जैसे the one described here, लेकिन अन्य (शायद बेहतर) पुस्तकालय मौजूद हो सकते हैं।

2

क्या हम लीक, या उनसे बचने के लिए कोड के तरीके खोजने के लिए टूल की बात कर रहे हैं?

पूर्व के लिए, ऊपर उल्लिखित वाल्ग्रिंड, या आईबीएम उपकरण के तर्कसंगत सूट यदि आपके पास लाइसेंस है। डॉ डोब्स Compuware के BoundsChecker की सिफारिश की लेकिन यह है कि 2002

था बाद में के लिए देखें: एक स्मार्ट सूचक

C++ idiom to avoid memory leaks?

http://www.cprogramming.com/tutorial/memory_debugging_parallel_inspector.html

http://scottmcpeak.com/memory-errors/

http://www.yolinux.com/TUTORIALS/C++MemoryCorruptionAndMemoryLeaks.html

1

का प्रयोग करें, जैसे std::shared_ptr<t> (सी ++ 0x), std::tr1::shared_ptr<t> (टीआर 1), या boost::shared_ptr<t>। बेशक इस समाधान केवल सी के साथ ++ काम करता है - आप सी में अपने दम पर कर रहे हैं

2

स्मार्ट संकेत वस्तु जीवन काल का बहीखाता स्वचालित में बहुत उपयोगी हो सकते हैं:

http://ootips.org/yonat/4dev/smart-pointers.html

जहां संभव हो, उपयोग नए/हटाए जाने के बजाए आवंटित ऑब्जेक्ट्स को उनके प्रासंगिक क्षेत्रों के अंदर ढेर करें।

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

7

सी के लिए, एक अच्छा कोड संगठन मदद करता है। अर्थात। अपने कोडबेस पर malloc() और मुफ्त() को कॉल फेंक न दें। उन्हें दो कार्यों में केंद्रीकृत करें, फिर आपके पास सभी चेकिंग के लिए एक बिंदु है। सबसे आसान व्यक्ति सफल कॉलों की गणना करना और कार्यक्रम से बाहर निकलने के लिए जांच कर सकता है कि वे संतुलित हैं।

static unsigned long mymem_count_alloc = 0; 
static unsigned long mymem_count_free = 0; 

void *mymem_alloc (size_t size) 
{ 
    void *p; 

    p = malloc(size); 
    if (p) 
    { 
     mymem_count_alloc++; 
    } 
    else 
     error logging/handling/signaling 

    return (p); 
} 

void mymem_free (void *p) 
{ 
    if (p) 
    { 
     free(p); 
     mymem_count_free++; 
    } 
} 

void mymem_check (void) 
{ 
    if (mymem_count_alloc != mymem_count_free) 
     error alert 
} 

आप इसे विभिन्न डेटा संरचनाओं के लिए जारी रख सकते हैं। एक स्ट्रिंग के लिए आपको स्मृति आवंटित करने की आवश्यकता है, mystr_alloc और mystr_free का उपयोग करें। और इसी तरह। जब एक रिसाव इस तरह से पता चला है, तो आप इसे जल्दी से संकीर्ण कर सकते हैं।

+0

+1 मुख्य रूप से 'फॉर सी के लिए, एक अच्छा कोड संगठन मदद करता है ...'। व्यक्तिगत रूप से, मैं इस सटीक विधि का उपयोग नहीं करना चाहूंगा। मैं प्रत्येक विशेष डेटा प्रकार को बनाने/नष्ट करने के लिए कार्यों के उपयोग को मजबूर करने के लिए अपारदर्शी डेटा संरचनाओं का उपयोग करने के लिए जाऊंगा। गिनती इन डेटा संरचनाओं में बदलाव/कार्यों को नष्ट कर देगी। इसके लिए आपको अपने कोड को स्पष्ट रूप से व्यवस्थित करने की आवश्यकता है, क्योंकि इसके लिए गन्दा होना आसान है। यह कई रिसावों को पकड़ने के लिए पर्याप्त होगा, और एरे में बाड़ पोस्ट त्रुटियों को पकड़ने के लिए वाल्ग्रिंड बहुत अच्छा है। –

+0

यह कहकर, यह विधि अभी भी उपयोगी होगी, लेकिन मैं निश्चित रूप से इसका उपयोग सशर्त होना चाहता हूं: यह डीबग बिल्ड के लिए मॉलोक/फ्री को प्रतिस्थापित करता है, लेकिन रिलीज बिल्ड में मॉलोक/फ्री का उपयोग किया जाता है। –

+0

@ जेम्स: मैं भी बना/नष्ट दृष्टिकोण के साथ जाता हूं। लेकिन वहां, मॉलोक के लिए रैपर फ़ंक्शंस/इनके समान मुक्त हमेशा उपयोग किए जाते हैं, इस उदाहरण के रूप में थोड़ा अधिक परिष्कृत। त्रुटि प्रबंधन भाग हमेशा जरूरी है, और लाइब्रेरी फ़ंक्शन को कॉल करते समय ** ** ** ** आवश्यक है, तो यह या तो फ़ंक्शन का हिस्सा बनना चाहिए या फ़ंक्शन में हेरफेर संभव नहीं होने पर एक रैपर में रखा जाना चाहिए , डीआरवाई सिद्धांत के संबंध में। http://stackoverflow.com/questions/1529679/how-do-you-program-safely-outside-of-a-managed-code-environment/1530581#1530581 – Secure

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