2012-03-29 10 views
6

चर्चा से here शुरू कर दिया, मैं निम्नलिखित कोड एक स्मृति रिसाव है कि क्या जानना चाहते हैं:एक गतिशील आवंटित ऑब्जेक्ट पर हमेशा एक स्मृति रिसाव को हटाने पर कॉल नहीं कर रहा है?

int main() 
{ 
    new int(); 
    //or 
    int* x = new int(); 
    return 0; 
} 

मैं जानता हूँ कि स्मृति ओएस द्वारा पुन: दावा है, लेकिन यह एक रिसाव वैसे भी है? मेरा मानना ​​है कि यह है।

मेमोरी रिसाव क्या परिभाषित करता है? मैं केवल मानक में एक संदर्भ पा सकता था, और यह बहुत उपयोगी नहीं था।

संपादित करें: मैं बहस शुरू नहीं करना चाहता - "मुझे लगता है कि ..." मैं जिस तरह का उत्तर ढूंढ रहा हूं वह नहीं है। मैं ज्यादातर स्रोतों में रूचि रखता हूं - सी ++ किताबें या वेबसाइटें या जो भी इसके बारे में कहना है।

+3

एक स्मृति रिसाव बस आवंटित स्मृति है लेकिन मुक्त नहीं है। –

+0

@ जोचिमपिलबोर्ग मैं लीक चर्चा में यही कह रहा हूं। जेम्स कह रहे हैं कि यह स्मृति की क्रमिक हानि है। मुझे कोई संतोषजनक स्रोत नहीं मिला। –

+0

@ जोचिम जो बहुत आसान है। आवंटित स्मृति आपकी परिभाषा के अनुसार पहले से ही एक स्मृति रिसाव –

उत्तर

1

दूसरा मामला स्मृति रिसाव नहीं है।
यह रिसाव नहीं है क्योंकि आपके पास अभी भी आवंटित स्मृति की एक सूचक है।
परिभाषा से चिपक एक स्मृति रिसाव मैं चाहते हैं परिभाषित करने के लिए जो valgrind उपयोग की तरह स्मृति विश्लेषण उपकरणों के सबसे:

मेमोरी आवंटित किया गया था और बाद में रिहा कर दिया नहीं जा सकता क्योंकि कार्यक्रम अब आबंटित स्मृति के लिए किसी भी संकेत दिए गए है ब्लॉक।

+1

+1 मैं इसे जानता था, इसलिए मैंने दोनों संस्करणों को पोस्ट किया। तो पहला वाला है, भले ही यह लगातार लीक न हो? –

+2

+1: एक छोटी, संक्षिप्त परिभाषा: 'कोड चलाने से पहुंचने योग्य वस्तुएं, लेकिन स्मृति में अभी भी संग्रहीत हैं' –

+0

@ लचियनग्रिगोर: मैंने उद्देश्य से पहले परिदृश्य पर टिप्पणी करने से रोक दिया क्योंकि आपका प्रश्न कहता है, * "मुझे लगता है कि ... नहीं है जिस तरह का उत्तर मैं ढूंढ रहा हूं "*। खैर, चूंकि आपने पूछा, मुझे लगता है कि पहला परिदृश्य एक रिसाव है, और मुझे यकीन है कि valgrind सहमत है लेकिन फिर फिर यह केवल मुझे और valgrind सोच है, कुछ मानक नहीं :) –

1

मैं एक स्मृति इस तरह से रिसाव को परिभाषित करेगा

क) यह स्मृति

ख) यह कोई आवेदन

ग) यह कोई और अधिक सुलभ है, और इसलिए है के लिए अधिक उपयोगी है लेता है कोई और हटाने योग्य

इसके अनुसार मैं आपके नमूना को स्मृति रिसाव के रूप में न्याय दूंगा। आपका नमूना एक अनैतिक रिसाव दिखाता है। एक महत्वपूर्ण रिसाव लगातार स्मृति ले रहा है, एप्लिकेशन तब तक हो सकता है जब तक कि

4

उपरोक्त कोड में वास्तव में एक रिसाव है। अधिक महत्वपूर्ण बात यह है कि, यदि int आवंटित करने के बजाय, आपने एक विशेष ऑब्जेक्ट आवंटित किया है, तो सर्वर कनेक्शन ऑब्जेक्ट कहें, यदि आप कभी भी ठीक से साफ नहीं करते हैं और delete पर कॉल करते हैं, तो ऑब्जेक्ट का विनाशक कभी नहीं चलता है, जो आपके सर्वर कनेक्शन की आवश्यकता होने पर महत्वपूर्ण हो सकता है विशेष साफ कोड करने के लिए (फाइलों, आदि को लिखें)।

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

इसके अलावा, शायद सबसे महत्वपूर्ण बात यह है कि आप प्रोग्रामर मेमोरी रिसाव मानते हैं। आपको संसाधन के रूप में स्मृति पर विचार करना चाहिए जिसे आपके अपने मॉडल के अनुसार प्रबंधित किया जाना चाहिए। this article पढ़ने पर विचार करें जो कुछ संसाधन आवंटन और प्रबंधन मॉडल पर चर्चा करता है। आरएआईआई (संसाधन अधिग्रहण प्रारंभिकरण) और स्मार्ट पॉइंटर्स (या कम से कम स्मार्ट पॉइंटर्स का विचार और संदर्भ गिनती का विचार) पर विचार करें।

+0

कोई मुझे -1 में भरना चाहता है? – Chris

+0

वही यहाँ। हमारे उत्तरों के साथ क्या गलत है यह जानने के लिए सबसे अच्छा है ताकि अगर वे गलत हैं तो हम उन्हें हटा/संपादित कर सकते हैं। –

+0

मेमोरी रिसाव का क्या मतलब है इसका कोई संदर्भ नहीं है। वास्तव में सवाल का जवाब नहीं देता है। –

-1

हां, 4 बाइट्स का रिसाव है क्योंकि new द्वारा आवंटित स्मृति delete डी नहीं है और आवेदन के जीवन के दौरान यह एक रिसाव है।

इस लिंक से:

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

Memory leak description: Memory is allocated but not released causing an application to consume memory reducing the available memory for other applications and eventually causing the system to page virtual memory to the hard drive slowing the application or crashing the application when than the computer memory resource limits are reached. The system may stop working as these limits are approached.

+0

लेकिन यह - "एप्लिकेशन को अन्य अनुप्रयोगों के लिए उपलब्ध स्मृति को कम करने के लिए स्मृति उत्पन्न करने का कारण बनता है" - लागू नहीं होता है। –

+0

यदि लूप में कोई एप्लिकेशन लीकिंग मेमोरी है और यह एप्लिकेशन लंबे समय तक चल रहा है, तो सिस्टम धीमा हो जाएगा। बेशक यह स्मृति लीकिंग की मात्रा पर निर्भर करता है। आपके उदाहरण में रिसाव सिस्टम को धीमा करने का कारण नहीं बनता है। – Sanish

+0

मैंने आपको कोड दिया, और वहां कोई लूप नहीं है। –

1

यह व्यक्तिपरक/बहस का मुद्दा है।

मेरी राय में संसाधन (स्मृति ओएस द्वारा प्रदान किए गए संसाधनों में से एक है) लीक के दो स्तर हैं: ओएस-स्तर और एप्लिकेशन स्तर। कृपया ध्यान दें कि नाम कस्टम हैं और उनके लिए एक बेहतर उपयुक्त तकनीकी शब्द हो सकता है।

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

एप्लिकेशन समाप्त होने के बाद ओएस-स्तरीय रिसाव मौजूद नहीं रहेगी। आम तौर पर कुछ अन्य संसाधन उस श्रेणी (फाइलें) में आते हैं, लेकिन स्मृति नहीं। हालांकि, मैं गारंटी नहीं दे सकता कि कोई ऑपरेटिंग सिस्टम/प्लेटफार्म नहीं है जो लीक मेमोरी को साफ नहीं करता है। मर्फी के कानून से शायद आज भी इस तरह का मंच इस्तेमाल किया जाता है। किसी भी स्मृति आवंटन किया गया है कि स्पष्ट रूप से एपीपी द्वारा हटाया नहीं -

तो जब मैं कहता हूँ/लिखने "स्मृति रिसाव" मैं अनुप्रयोग स्तर रिसाव के बारे में बात कर रहा हूँ। प्रत्येक आवंटन, यहां तक ​​कि जानबूझकर, श्रेणी में आता है। इसके अलावा, सामान्य रूप से स्मृति आवंटन प्रोफाइलर्स और इसी तरह के उपकरण आपके "जानबूझकर लीक",

के बारे में शिकायत करेंगे, इसलिए, आपके कोड में रिसाव है।

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

+0

यदि आप सामान्य रूप से संसाधनों (और केवल स्मृति नहीं) के बारे में बात कर रहे हैं, तो ओएस सब कुछ साफ करने में सक्षम नहीं हैं। एक अस्थायी फ़ाइल जिसे आप हटाने में विफल रहते हैं वह एक संसाधन रिसाव है जिसे ओएस द्वारा साफ नहीं किया जाएगा। (बाकी के लिए, आपने "लीक" शब्द की पूरी तरह से नई और बेकार परिभाषा का आविष्कार किया है।) –

5

यह इस बात पर निर्भर करता है कि आप "रिसाव" को कैसे परिभाषित करते हैं। सबसे स्पष्ट परिभाषा के अनुसार, और केवल उपयोगी एक, यह कम से कम एप्लिकेशन स्तर पर रिसाव नहीं है। एक बाल्टी रिसाव नहीं होती है क्योंकि आप जानबूझकर पानी की एक सीमित मात्रा से बचने की अनुमति देते हैं। और व्यावहारिक रूप से बोलते हुए, कोई एप्लिकेशन विफल नहीं होता है क्योंकि आप जानबूझकर प्रोग्राम के अंत से परे बने रहने के लिए ऑब्जेक्ट्स के बाउंड सेट को अनुमति देते हैं।

स्मृति रिसाव के संबंध में, शब्द की हमारी धारणा "लीक चेकर्स" द्वारा रंगी गई है --- शुद्ध या वालग्रिंड जैसे कार्यक्रम। उनकी भूमिका लीक (अन्य चीजों के साथ) ढूंढना है, लेकिन उनके पास का कोई तरीका नहीं है जो जानबूझकर जानना है, और क्या नहीं है, और क्या बाध्य है, और क्या नहीं है। इसलिए उन्होंने अन्य परिभाषाओं का आविष्कार किया: एक ऑब्जेक्ट जो पहुंच योग्य नहीं है "लीक" है (और वास्तविक कोड में एक अच्छी संभावना है कि यह सत्य है), या एक ऑब्जेक्ट जो स्थिर वस्तुओं के विनाशकों के बाद हटा नहीं गया है निष्पादित किया गया है "लीक"।इस बाद के मामले में में, परिभाषा स्पष्ट रूप से गलत है, और बेकार है। लेकिन ऐसे कई मामले हैं जहां ऐसी चीजें लीक होती हैं कि कम से कम उनके बारे में चेतावनी देना उचित है ("संभावित लीक"), प्रदान किए गए विशिष्ट मामलों को फ़िल्टर करने का एक तरीका है। (दोनों शुद्ध और वेलग्रिंड पहचान नहीं सभी इन मामलों में से वास्तव में लीक कर रहे हैं कि, और उनके पता लगाने के लिए विभिन्न फ़िल्टरिंग प्रक्रिया को प्रदान करते हैं।) अच्छी तरह से है सभी जिनमें से और अच्छे — मैं बहुत खुश हम इस तरह के उपकरणों — लेकिन है कि कर रहा हूँ हमें उन्हें भाषा को विकृत करने की अनुमति नहीं देनी चाहिए।

और एक अंतिम अनुस्मारक: मानक कहता है कि मानक iostream ऑब्जेक्ट्स (std::cout, आदि) कभी विनाश नहीं किया जाएगा। तो कोई भी बफर वे आवंटित करेंगे (शायद) कभी मुक्त नहीं किया जाएगा। निश्चित रूप से उनके में कोई भी इन दिमागों को "लीक" पर विचार नहीं करेगा।

+1

से बाहर न हो जाए, यह निश्चित रूप से एक दिलचस्प दृष्टिकोण है, मेरे पास था कभी * सीमित रिसाव * परिदृश्य के बारे में सोचा नहीं, लेकिन यह समझ में आता है। मुझे प्रबुद्ध महसूस होता है। –

+0

@MatthieuM। व्यावहारिक दृष्टिकोण से, "बाध्यता" का मुद्दा मेरे लिए महत्वपूर्ण लगता है। और यह गैर प्रोग्रामिंग संदर्भों में एक "रिसाव" के रूप में मुझे सहजता से सोचने के साथ फिट बैठता है। लेकिन मरियम-वेबस्टर के साथ जांच से पता चलता है कि गैर प्रोग्रामिंग संदर्भों में भी, यह स्पष्ट नहीं है। –

+0

शब्द "रिसाव" प्रोग्रामिंग और गैर-प्रोग्रामिंग संदर्भों में बाध्य और असंबद्ध परिदृश्य दोनों को इंगित कर सकता है। तथ्य यह है कि पांच गैलन बाल्टी में छेद से केवल पांच-गैलन तरल भाग सकते हैं इसका मतलब यह नहीं है कि छेद "रिसाव" नहीं है। और यदि कार्यक्रम बाहर निकलने के बाद वस्तुएं बेकार रहती रहती हैं, तो वे लीक हो जाते हैं। दूसरी तरफ, यदि प्रोग्राम को फिर से चलाने से वस्तुएं पुन: उपयोग की जाएंगी, तो वे तथ्य यह है कि वे पुन: प्रयोज्य हैं इसका अर्थ है कि वे "बेकार" नहीं हैं। और अगर ओएस उन्हें समस्या से पहले साफ कर देगा, तो वे लीक नहीं हो जाते हैं। – supercat

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