जब आप मॉलॉक के बाद मुक्त नहीं होते हैं तो वास्तव में क्या होता है?


538

यह कुछ ऐसा है जो मुझे अब उम्र के लिए परेशान कर रहा है।

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

पहला, अगर मेरे पास कोड है जो कुछ इस तरह है:

int main()
{
    char *a = malloc(1024);
    /* Do some arbitrary stuff with 'a' (no alloc functions) */
    return 0;
}

यहाँ वास्तविक परिणाम क्या है? मेरी सोच यह है कि प्रक्रिया मर जाती है और फिर ढेर स्थान वैसे भी चला जाता है इसलिए कॉल को गायब करने में कोई नुकसान नहीं है free(हालांकि, मैं इसे बंद करने, बनाए रखने और अच्छे अभ्यास के लिए वैसे भी होने के महत्व को पहचानता हूं)। क्या मैं इस सोच में सही हूँ?

दूसरा, मान लीजिए कि मेरे पास एक प्रोग्राम है जो शेल की तरह थोड़ा सा काम करता है। उपयोगकर्ता चर की तरह घोषित कर सकते हैं aaa = 123और जिन्हें बाद में उपयोग के लिए कुछ गतिशील डेटा संरचना में संग्रहीत किया जाता है। स्पष्ट रूप से, यह स्पष्ट प्रतीत होता है कि आप कुछ समाधान का उपयोग करेंगे जो कुछ * आवंटन फ़ंक्शन (हैशमैप, लिंक की गई सूची, ऐसा कुछ) को कॉल करेगा। इस तरह के कार्यक्रम के लिए, यह कॉल करने के बाद कभी भी मुक्त होने का कोई मतलब नहीं है mallocक्योंकि ये चर कार्यक्रम के निष्पादन के दौरान हर समय मौजूद रहना चाहिए और इसे सांख्यिकीय रूप से आवंटित स्थान के साथ लागू करने का कोई अच्छा तरीका नहीं है (जिसे मैं देख सकता हूं)। क्या यह खराब डिज़ाइन है कि स्मृति का एक गुच्छा है जो आवंटित किया गया है लेकिन केवल समाप्त होने वाली प्रक्रिया के हिस्से के रूप में मुक्त किया गया है? यदि हां, तो विकल्प क्या है?


7
@NTDLS रेटिंग सिस्टम का जादू वास्तव में एक बार काम कर रहा है: 6 साल और "अधिक योग्य" उत्तर वास्तव में शीर्ष पर पहुंच गया है।
zxq9

15
नीचे दिए गए लोग कहते हैं कि एक अच्छा आधुनिक ओएस सफाई करता है लेकिन क्या होगा अगर कोड कर्नेल मोड में चल रहा हो (उदाहरण के लिए, प्रदर्शन कारणों से)? क्या कर्नेल मोड प्रोग्राम (उदाहरण के लिए लिनक्स में) सैंडबॉक्स किए गए हैं? यदि नहीं, तो मुझे विश्वास है कि आपको एबॉर्ट () के साथ किसी भी असामान्य समाप्ति से पहले ही, मुझे सब कुछ मैन्युअल रूप से मुक्त करने की आवश्यकता होगी।
डॉ। पर्सन II II

3
@ Dr.PersonPersonII हाँ, कर्नेल मोड में चलने वाले कोड को आमतौर पर सब कुछ मैन्युअल रूप से मुक्त करना पड़ता है।
zwol

1
मैं जोड़ना चाहूंगा कि free(a)वास्तव में स्मृति को वास्तव में मुक्त करने के लिए कुछ भी नहीं करना है! यह केवल मॉलोक के परिवाद के कार्यान्वयन में कुछ बिंदुओं को रीसेट करता है जो कि बड़े मिमीपेड मेमोरी पेज (जिसे आमतौर पर "हीप" कहा जाता है) के अंदर मेमोरी की उपलब्ध मात्रा पर नज़र रखता है। वह पृष्ठ अब भी केवल तभी मुक्त किया जाएगा जब आपका कार्यक्रम समाप्त हो जाएगा, इससे पहले नहीं।
मार्को बोनेली

1
नि: शुल्क () वास्तव में मेमोरी को जारी कर सकता है या नहीं भी कर सकता है। यह ब्लॉक को केवल मुक्त करने के लिए चिह्नित कर सकता है, बाद में पुनः प्राप्त किया जा सकता है, या इसे एक मुक्त सूची में जोड़ सकता है। यह इसे आसन्न मुक्त ब्लॉकों में विलय कर सकता है, या ऐसा करने के लिए बाद में आवंटन के लिए छोड़ सकता है। यह सभी कार्यान्वयन विवरण है।
जॉर्डन ब्राउन

जवाबों:


378

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

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

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

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


16
शायद यह उल्लेख करना भी अच्छा होगा कि हर कोई एक आधुनिक ऑपरेटिंग सिस्टम का उपयोग नहीं कर रहा है, अगर कोई आपका प्रोग्राम लेता है (और यह अभी भी ओएस पर चलता है जो मेमोरी को पुनर्प्राप्त नहीं करता है) इसे चलाता है तो जीजी।
user105033

79
मैं वास्तव में इस उत्तर को गलत मानता हूं। किसी के साथ एक के बाद एक संसाधनों का सौदा हमेशा किया जाना चाहिए, यह फाइल हैंडल / मेमोरी / मक्सक्स है। उस आदत के होने से, कोई भी सर्वर बनाते समय उस तरह की गलती नहीं करेगा। कुछ सर्वरों को 24x7 चलाने की उम्मीद है। उन मामलों में, किसी भी प्रकार के रिसाव का मतलब है कि आपका सर्वर अंततः उस संसाधन से बाहर चला जाएगा और किसी तरह से लटका / दुर्घटनाग्रस्त हो जाएगा। एक छोटी उपयोगिता कार्यक्रम, हां एक रिसाव यह बुरा नहीं है। कोई भी सर्वर, कोई भी रिसाव मौत है। अपने आप को एक एहसान करो। अपने आप के बाद साफ करो। यह एक अच्छी आदत है।
EvilTeach

120
"हालांकि, इसका एक हिस्सा यह है कि इसे जल्द से जल्द याद रखने की अच्छी शैली मानी जाती है, इसके लिए आपको किसी और चीज की जरूरत नहीं है, और जो भी आपके पास अभी भी प्रोग्राम से बाहर है, उसे मुक्त करने के लिए।" क्या आप गलत मानते हैं?
पॉल टॉमब्लिन

24
यदि आपके पास एक मेमोरी स्टोर है, जिसे आपको उस समय तक की आवश्यकता है, जब तक कि कार्यक्रम से बाहर नहीं निकल जाता है, और आप एक आदिम OS पर नहीं चल रहे हैं, तो आपके बाहर निकलने से ठीक पहले मेमोरी को मुक्त करना एक शैलीगत विकल्प है, दोष नहीं।
पॉल टॉम्बलिन

30
@Paul - सिर्फ EvilTeach से सहमत, मुक्त स्मृति के लिए अच्छी शैली नहीं मानी जाती है, यह गलत है कि मुक्त स्मृति नहीं। आपका शब्दांकन इस बारे में उतना ही महत्वपूर्ण है जितना कि रूमाल पहनना महत्वपूर्ण है जो आपकी टाई से मेल खाता है। दरअसल, यह पैंट पहनने के स्तर पर है।
हीथ हनीनकुट

110

हां, आप सही हैं, आपका उदाहरण कोई नुकसान नहीं करता है (कम से कम अधिकांश आधुनिक ऑपरेटिंग सिस्टम पर नहीं)। प्रक्रिया से बाहर निकलते ही आपकी प्रक्रिया द्वारा आवंटित सभी मेमोरी को ऑपरेटिंग सिस्टम द्वारा वापस प्राप्त कर लिया जाएगा।

स्रोत: आवंटन और GC मिथकों (पोस्टस्क्रिप्ट अलर्ट!)

आवंटन मिथक 4: गैर-कचरा एकत्र किए गए कार्यक्रमों को हमेशा उन सभी मेमोरी से निपटना चाहिए जो वे आवंटित करते हैं।

सच्चाई: अक्सर निष्पादित कोड में लीक किए गए डीलॉलेशन बढ़ते लीक का कारण बनते हैं। वे शायद ही स्वीकार्य हैं। लेकिन ऐसे प्रोग्राम जो प्रोग्राम से बाहर होने तक सबसे अधिक आवंटित मेमोरी को बनाए रखते हैं, अक्सर किसी भी हस्तक्षेप किए हुए डीलडाउन के बिना बेहतर प्रदर्शन करते हैं। अगर मुफ्त नहीं है तो मल्लोक को लागू करना बहुत आसान है।

ज्यादातर मामलों में, प्रोग्राम से बाहर निकलने से ठीक पहले मैमोरी डील करना व्यर्थ है। ओएस वैसे भी इसे पुनः प्राप्त करेगा। मृत वस्तुओं में नि: शुल्क स्पर्श और पृष्ठ होगा; OS नहीं होगा

परिणाम: "लीक डिटेक्टरों" से सावधान रहें जो आवंटन की गणना करते हैं। कुछ "लीक" अच्छे हैं!

उस ने कहा, आपको वास्तव में सभी मेमोरी लीक से बचने की कोशिश करनी चाहिए!

दूसरा सवाल: आपका डिजाइन ठीक है। यदि आपको अपने एप्लिकेशन के बाहर निकलने तक कुछ स्टोर करने की आवश्यकता है, तो डायनेमिक मेमोरी आवंटन के साथ ऐसा करने के लिए ठीक है। यदि आप आवश्यक आकार को नहीं जानते हैं, तो आप स्टैटिकली आवंटित मेमोरी का उपयोग नहीं कर सकते।


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

3
संभवत: वहाँ थे (प्रारंभिक विंडोज, प्रारंभिक मैक ओएस), और शायद अभी भी हैं, ओएस जो बाहर निकलने से पहले स्मृति को मुक्त करने के लिए प्रक्रियाओं की आवश्यकता होती है अन्यथा अंतरिक्ष को पुनः प्राप्त नहीं किया जाता है।
पीट किरखम

यह पूरी तरह से ठीक है, जब तक कि आप मेमोरी विखंडन या मेमोरी से बाहर निकलने की परवाह नहीं करते हैं - आप ऐसा बहुत अधिक करते हैं और आपके एप्लिकेशन का प्रदर्शन गायब हो जाएगा। कठिन तथ्यों के अलावा, हमेशा सबसे अच्छा अभ्यास और अच्छी आदत निर्माण का पालन करें।
NTDLS

1
मेरे पास एक स्वीकृत उत्तर है जो वर्तमान में -11 के बारे में बैठा है, इसलिए वह रिकॉर्ड के लिए दौड़ में भी नहीं है।
पॉल टॉम्बलिन

8
मुझे लगता है कि "लीक डिटेक्टर के कारण" कहकर मुफ्त में () 'मेमोरी को इंगेज करने की जरूरत को समझाना गलत है।' यह कहने के समान है "आपको एक प्ले स्ट्रीट में धीरे-धीरे ड्राइव करना होगा क्योंकि पुलिस के लोग स्पीड कैमरा के साथ आपकी प्रतीक्षा कर सकते हैं"।
सेबस्टियन माच

57

=== भविष्य में प्रूफिंग और कोड के पुन: उपयोग के बारे में क्या ? ===

यदि आप वस्तुओं को मुक्त करने के लिए कोड नहीं लिखते हैं, तो आप कोड का उपयोग केवल सुरक्षित होने के लिए कर रहे हैं, जब आप बंद की जा रही प्रक्रिया से मुक्त होने वाली मेमोरी पर निर्भर हो सकते हैं ... यानी छोटा एक बार का उपयोग परियोजनाएं या "थ्रो-दूर" [1] परियोजनाएं) ... जहां आप जानते हैं कि प्रक्रिया कब समाप्त होगी।

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


[१] "फेंक-दूर" परियोजनाओं के बारे में। "थ्रो-दूर" परियोजनाओं में उपयोग किए जाने वाले कोड का एक तरीका नहीं है कि उन्हें फेंक दिया जाए। अगली बात जो आपको पता है कि दस साल बीत चुके हैं और आपका "थ्रो-दूर" कोड अभी भी उपयोग किया जा रहा है)।

मैंने कुछ लोगों के बारे में एक कहानी सुनी, जिन्होंने अपने हार्डवेयर को बेहतर बनाने के लिए सिर्फ मनोरंजन के लिए कुछ कोड लिखे। उन्होंने कहा " सिर्फ एक शौक, बड़ा और पेशेवर नहीं होगा "। वर्षों बाद बहुत से लोग उसके "शौक" कोड का उपयोग कर रहे हैं।


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

कल का आवेदन आज का लाइब्रेरी फंक्शन है, और कल इसे एक लंबे समय तक रहने वाले सर्वर से जोड़ा जाएगा जो इसे हजारों बार कहता है।
एड्रियन मैक्कार्थी

1
@ AdrianMcCarthy: यदि कोई फ़ंक्शन यह जाँचता है कि क्या एक स्थिर सूचक शून्य है, malloc()तो यदि यह है, तो इसे प्रारंभ कर देता है और यदि सूचक अभी भी अशक्त है, तो इस तरह के फ़ंक्शन को सुरक्षित रूप से एक मनमाना संख्या का उपयोग किया जा सकता है, भले ही freeकभी न कहा जाए। मुझे लगता है कि मेमोरी लीक में अंतर करना संभव है, जो भंडारण की एक अनबाउंड राशि का उपयोग कर सकता है, बनाम ऐसी स्थितियां जो केवल एक परिमित और अनुमानित मात्रा में भंडारण को बर्बाद कर सकती हैं।
सुपरकैट

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

1
@AdrianMcCarthy: कोड को अब स्थैतिक पॉइंटर का उपयोग करने के लिए बदलने से संभवतः पॉइंटर को किसी प्रकार के "संदर्भ" ऑब्जेक्ट में ले जाने की आवश्यकता नहीं होगी, और ऐसी वस्तुओं को बनाने और नष्ट करने के लिए कोड जोड़ना होगा। यदि पॉइंटर हमेशा होता है nullयदि कोई आवंटन मौजूद नहीं है, और जब कोई आवंटन मौजूद होता है, तो गैर-शून्य, कोड को आवंटन से मुक्त करता है और पॉइंटर को nullतब सेट करता है जब एक संदर्भ नष्ट हो जाता है, सीधा होगा, विशेष रूप से सब कुछ के साथ तुलना में जो करना होगा। स्थैतिक वस्तुओं को संदर्भ संरचना में ले जाने के लिए।
सुपरकैट

52

आप सही हैं, कोई नुकसान नहीं हुआ है और यह सिर्फ बाहर निकलने के लिए तेज़ है

इसके कई कारण हैं:

  • सभी डेस्कटॉप और सर्वर वातावरण बस बाहर निकलने पर पूरे मेमोरी स्पेस को जारी करते हैं ()। वे प्रोग्राम-आंतरिक डेटा संरचनाओं जैसे कि ढेर से अनजान हैं।

  • लगभग सभी free()कार्यान्वयन कभी भी मेमोरी को ऑपरेटिंग सिस्टम पर नहीं लौटाते हैं।

  • इससे भी महत्वपूर्ण बात, यह समय की बर्बादी है जब निकास () से ठीक पहले किया जाता है। बाहर निकलने पर, मेमोरी पेज और स्वैप स्पेस बस जारी किए जाते हैं। इसके विपरीत, मुफ्त () कॉल की एक श्रृंखला CPU समय को जलाएगी और डिस्क पेजिंग ऑपरेशन, कैश मिस और कैश निष्कासन में परिणाम कर सकती है।

के बारे में possiblility justifing पुन: उपयोग के भविष्य कोड की निश्चितता व्यर्थ ऑप्स के: एक विचार है कि लेकिन यह यकीनन नहीं है चंचल रास्ता। YAGNI!


2
मैंने एक बार एक परियोजना पर काम किया था, जहां हमने एक प्रोग्राम मेमोरी उपयोग को समझने के लिए बहुत कम समय बिताया था (हमें इसका समर्थन करने की आवश्यकता थी, हमने इसे नहीं लिखा था)। अनुभव के आधार पर मैं आपके दूसरे बुलेट से सहमत हूं। हालाँकि, मैं आपको (या किसी को) अधिक प्रमाण देना चाहता हूँ कि यह सच है।
user106740

3
कोई बात नहीं, जवाब मिला: stackoverflow.com/questions/1421491/… । आपका धन्यवाद!
user106740

@aviggiano जिसे YAGNI कहा जाता है।
v.oddou

YAGNI सिद्धांत दोनों तरीकों से काम करता है: आपको शटडाउन पथ को अनुकूलित करने की आवश्यकता नहीं है। समयपूर्व अनुकूलन और वह सब।
एड्रियन मैकार्थी

26

मैं पूरी तरह से उन सभी से असहमत हूं जो कहते हैं कि ओपी सही है या कोई नुकसान नहीं है।

हर कोई आधुनिक और / या विरासत ओएस के बारे में बात कर रहा है।

लेकिन क्या होगा अगर मैं ऐसे माहौल में हूं जहां मेरे पास बस ओएस नहीं है? जहां कुछ भी नहीं है?

कल्पना कीजिए कि अब आप थ्रेड स्टाइल इंटरप्ट का उपयोग कर रहे हैं और मेमोरी आवंटित कर रहे हैं। सी मानक में आईएसओ / आईईसी: 9899 स्मृति के जीवनकाल के रूप में कहा गया है:

7.20.3 मेमोरी प्रबंधन कार्य

1 कॉलोक, मॉलोक और रियललोक कार्यों के लिए लगातार कॉल द्वारा आवंटित भंडारण का क्रम और संदर्भ अनपेक्षित है। यदि आबंटन सफल हो जाता है तो पॉइंटर लौटाया जाता है, ताकि इसे किसी भी प्रकार की वस्तु के लिए पॉइंटर को सौंपा जा सके और फिर इस तरह के ऑब्जेक्ट या इस तरह के ऑब्जेक्ट्स का उपयोग अंतरिक्ष में आवंटित किए जाने तक किया जा सके (जब तक कि अंतरिक्ष को स्पष्ट रूप से निपटा नहीं जाता है) । एक आबंटित वस्तु का जीवनकाल आवंटन से तब तक निकलता है जब तक कि सौदा नहीं हो जाता। […]

इसलिए यह नहीं दिया जाना चाहिए कि पर्यावरण आपके लिए मुफ्त काम कर रहा है। अन्यथा इसे अंतिम वाक्य में जोड़ा जाएगा: "या जब तक कार्यक्रम समाप्त न हो जाए।"

तो दूसरे शब्दों में: स्मृति को मुक्त करना केवल बुरा अभ्यास नहीं है। यह गैर पोर्टेबल पैदा करता है और सी अनुरूप कोड नहीं। जिसे कम से कम 'सही, अगर निम्नलिखित: [...], पर्यावरण द्वारा समर्थित है' के रूप में देखा जा सकता है।

लेकिन उन मामलों में जहां आपके पास कोई ओएस नहीं है, कोई भी आपके लिए काम नहीं कर रहा है (मुझे पता है कि आप आमतौर पर एम्बेडेड सिस्टम पर मेमोरी को आवंटित और पुनः लोड नहीं करते हैं, लेकिन ऐसे मामले हैं जहां आप चाहते हो सकते हैं।)

इसलिए सामान्य सादे सी में बोलना (जिस पर ओपी को टैग किया गया है), यह केवल गलत और गैर पोर्टेबल कोड का उत्पादन कर रहा है।


4
एक प्रतिवाद यह है कि यदि आप एक एम्बेडेड वातावरण हैं, तो आप - डेवलपर के रूप में - पहली बार में आपके मेमोरी प्रबंधन में कहीं अधिक तेज़ होंगे। आमतौर पर, यह वास्तव में पहले से स्थैतिक मेमोरी को पूर्व-आबंटित करने के बिंदु पर होता है, बजाय किसी भी रनटाइम मॉलोक / रियलकॉल्स के।
जॉन गो-सोको

1
@lunarplasma: जबकि आप जो कह रहे हैं वह गलत नहीं है, इससे इस तथ्य में कोई बदलाव नहीं आता है कि भाषाओं का मानक क्या है, और हर कोई जो इसके खिलाफ / आगे कार्य करता है, वह सामान्य ज्ञान भी हो सकता है, सीमित कोड का उत्पादन कर रहा है। मैं समझ सकता हूं कि क्या कोई कहता है कि "मुझे इसकी परवाह नहीं है", क्योंकि पर्याप्त मामले हैं जहां यह ठीक है। लेकिन यह कि कम से कम उसे पता होना चाहिए कि उसे ध्यान क्यों नहीं है। और विशेष रूप से तब तक इसे छोड़ना नहीं चाहिए जब तक कि प्रश्न उस विशेष मामले से संबंधित न हो। और चूंकि ओपी सैद्धांतिक (स्कूल) पहलुओं के तहत सामान्य रूप से सी के बारे में पूछ रहा है। यह कहना ठीक नहीं है कि "आपको जरूरत नहीं है"!
धिन

2
अधिकांश वातावरणों में जहां ओएस नहीं है, कोई साधन नहीं है जिसके माध्यम से कार्यक्रम "समाप्त" कर सकते हैं।
सुपरकैट

@ सुपरकैट: जैसा कि मैंने पहले लिखा है: आप इसके बारे में सही हैं। लेकिन अगर कोई शिक्षण कारणों और स्कूल पहलुओं के संबंध में इसके बारे में पूछ रहा है, तो यह कहना सही नहीं है "आपको इसके बारे में सोचने की ज़रूरत नहीं है कि ज्यादातर समय यह मायने नहीं रखता है" भाषा का शब्द और व्यवहार। परिभाषा एक कारण के लिए दी गई है, और सिर्फ इसलिए कि अधिकांश वातावरण आपके लिए इसे संभालते हैं, आप यह नहीं कह सकते कि देखभाल करने की कोई आवश्यकता नहीं है। यही मेरा सवाल है।
ढिन

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

23

मैं निश्चित रूप से प्रत्येक आवंटित ब्लॉक को एक बार मुक्त करता हूं जब मुझे यकीन हो जाता है कि मैं इसके साथ कर रहा हूं। आज, मेरे कार्यक्रम का प्रवेश बिंदु हो सकता है main(int argc, char *argv[]), लेकिन कल यह foo_entry_point(char **args, struct foo *f)एक फ़ंक्शन पॉइंटर के रूप में हो सकता है और टाइप किया जा सकता है ।

इसलिए, अगर ऐसा होता है, तो अब मेरे पास एक रिसाव है।

आपके दूसरे प्रश्न के बारे में, अगर मेरे कार्यक्रम ने = 5 की तरह इनपुट लिया, तो मैं एक के लिए जगह आवंटित करूंगा, या बाद में एक = "फू" पर उसी स्थान को फिर से आवंटित करूंगा। यह तब तक आवंटित रहेगा:

  1. उपयोगकर्ता ने 'unset' टाइप किया
  2. मेरा क्लीनअप फ़ंक्शन दर्ज किया गया था, या तो एक सिग्नल की सर्विसिंग की गई या उपयोगकर्ता ने 'छोड़ दिया' टाइप किया।

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

एक अन्य मिथक है " यदि इसका मुख्य (), मुझे इसे खाली नहीं करना है ", तो यह गलत है। निम्नलिखित को धयान मे रखते हुए:

char *t;

for (i=0; i < 255; i++) {
    t = strdup(foo->name);
    let_strtok_eat_away_at(t);
}

यदि वह फोर्किंग / डीमॉनेटाइज़िंग (और हमेशा के लिए चलने वाले सिद्धांत) से पहले आया था, तो आपके प्रोग्राम ने अभी तक 255 बार अनिर्धारित आकार लीक किया है।

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

वास्तव में, उस गरीब आत्मा के प्रति दया करो जिसे अपना सामान बनाए रखना होता है जब आप अन्य चीजों पर जाते हैं .. तो उसे हाथ दें 'स्वच्छ स्वच्छ' ... :)


1
और हाँ, मैं एक बार एक टीम के साथी मुझे बता दिया था: <shudders> "मैं मुक्त () कॉल करने के लिए मुख्य () में की जरूरत कभी नहीं"
टिम पोस्ट

free() is cheapजब तक आपके पास जटिल संबंधों के साथ एक अरब डेटा संरचनाएं नहीं होती हैं, जिन्हें आपको एक-एक करके जारी करना होता है, डेटा संरचना को पीछे छोड़ते हुए सब कुछ जारी करने की कोशिश करना आपके शट डाउन समय में काफी वृद्धि कर सकता है, खासकर यदि उस डेटा संरचना का आधा हिस्सा पहले से ही बाहर है। बिना किसी लाभ के डिस्क को।
रेयान

3
@LieRyan आप के रूप में एक अरब, है, तो सचमुच इस विशेष जवाब का :) दायरे से बाहर तरीका है - एक अरब संरचनाओं, आप सबसे निश्चित अन्य समस्याओं पर विचार करने के एक विशेष डिग्री की आवश्यकता है
टिम पोस्ट

13

जब आप बाहर निकलते हैं तो स्मृति को छोड़ना पूरी तरह से ठीक है; मैलोक () मेमोरी को "हीप" नामक मेमोरी क्षेत्र से आवंटित करता है, और जब प्रक्रिया से बाहर निकलता है तो एक प्रक्रिया का पूरा ढेर मुक्त हो जाता है।

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


1
क्या Valgrind "लीक" और "अभी भी पहुंच से बाहर" के बीच एक बहुत अच्छा काम नहीं करता है?
क्रिस्टोफर

11
-1 "पूरी तरह से ठीक है" के लिए यह बिना कोडिंग मेमोरी को खाली करने के लिए खराब कोडिंग अभ्यास है। यदि उस कोड को एक पुस्तकालय में निकाला जाता था, तो इससे सभी जगहों पर बोलचाल बढ़ जाती थी।
डेविन बी

5
क्षतिपूर्ति करने के लिए +1। कंपी का जवाब देखें। freeपर exitसमय हानिकारक माना।
आर .. गिटहब स्टॉप हेल्पिंग ICE

11

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

संपादित करें: यह कहना 100% सही नहीं है कि अन्य चल रहे कार्यक्रम उस मेमोरी से वंचित हैं। ऑपरेटिंग सिस्टम हमेशा वर्चुअल मेमोरी ( </handwaving>) के लिए अपने प्रोग्राम को स्वैप करने की कीमत पर उन्हें इसका उपयोग करने दे सकता है । हालाँकि, यह है कि यदि आपका प्रोग्राम उस मेमोरी को मुक्त करता है जिसका वह उपयोग नहीं कर रहा है तो वर्चुअल मेमोरी स्वैप आवश्यक होने की संभावना कम है।


11

यह कोड आमतौर पर ठीक काम करेगा, लेकिन कोड के पुन: उपयोग की समस्या पर विचार करें।

आपने कुछ कोड स्निपेट लिखे होंगे जो आवंटित स्मृति को मुक्त नहीं करते हैं, यह इस तरह से चलाया जाता है कि स्मृति फिर स्वचालित रूप से पुनः प्राप्त हो जाती है। बिल्कुल ठीक लगता है।

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

उद्यमों में कोड का पुन: उपयोग विशिष्ट है। आमतौर पर कंपनी अपने कर्मचारियों के उत्पादन के सभी कोडों का मालिक होती है और जो भी कंपनी का मालिक होता है उसका हर विभाग पुन: उपयोग कर सकता है। इसलिए इस तरह के "सहज-दिखने वाले" कोड को लिखकर आप अन्य लोगों के लिए संभावित सिरदर्द का कारण बन सकते हैं। यह आपको निकाल दिया जा सकता है।


2
यह न केवल स्निपेट की नकल करने वाले किसी व्यक्ति की संभावना को ध्यान देने योग्य हो सकता है, बल्कि एक ऐसे कार्यक्रम की संभावना भी है जिसे किसी विशेष कार्रवाई को एक बार करने के लिए संशोधित करने के लिए लिखा गया था। ऐसे में, यह ठीक होगा कि मेमोरी को एक बार आबंटित किया जाए और फिर बिना किसी फ्रीज के बार-बार इस्तेमाल किया जाए, लेकिन हर एक्शन के लिए मेमोरी को आवंटित करना और छोड़ना (इसे फ्री किए बिना) विनाशकारी हो सकता है।
सुपरकैट

7

यहाँ वास्तविक परिणाम क्या है?

आपके कार्यक्रम ने मेमोरी को लीक कर दिया। आपके OS के आधार पर, यह पुनर्प्राप्त हो सकता है।

अधिकांश आधुनिक डेस्कटॉप ऑपरेटिंग सिस्टम प्रक्रिया समाप्ति पर लीक की गई मेमोरी को पुनर्प्राप्त करते हैं , जिससे समस्या को अनदेखा करना दुख की बात है, जैसा कि यहां कई अन्य उत्तरों द्वारा देखा जा सकता है।)

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

आप कर्नेल मोड में, या पुराने / एम्बेडेड ऑपरेटिंग सिस्टम पर चल सकते हैं जो ट्रेडऑफ़ के रूप में मेमोरी सुरक्षा को नियोजित नहीं करते हैं। (MMUs डाई स्पेस लेते हैं, मेमोरी प्रोटेक्शन पर अतिरिक्त सीपीयू साइकल खर्च होता है, और यह प्रोग्रामर से खुद को साफ करने के लिए पूछने के लिए बहुत ज्यादा नहीं है)।

आप अपनी पसंद के अनुसार किसी भी तरह से मेमोरी का उपयोग और पुनः उपयोग कर सकते हैं, लेकिन सुनिश्चित करें कि बाहर निकलने से पहले आपने सभी संसाधनों से निपट लिया हो।


5

वास्तव में ऑपरेटिंग सिस्टम में एक अंडरग्रेजुएट कोर्स के लिए OSTEP ऑनलाइन पाठ्यपुस्तक में एक अनुभाग है जो आपके प्रश्न पर चर्चा करता है।

संबंधित खंड पेज 6 पर मेमोरी एपीआई अध्याय में "फ्री मेमोरी को भूल जाना" है जो निम्नलिखित स्पष्टीकरण देता है:

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

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

दृश्यों के पीछे, ऑपरेटिंग सिस्टम "आभासी पतों" का अनुवाद करेगा जो उपयोगकर्ता भौतिक मेमोरी की ओर इशारा करते हुए वास्तविक पतों को देखता है।

हालाँकि, भौतिक मेमोरी जैसे संसाधनों को साझा करने के लिए ऑपरेटिंग सिस्टम की आवश्यकता होती है ताकि वे यह देख सकें कि कौन सी प्रक्रिया इसका उपयोग कर रही है। इसलिए यदि कोई प्रक्रिया समाप्त हो जाती है, तो यह प्रक्रिया की मेमोरी को पुनः प्राप्त करने के लिए ऑपरेटिंग सिस्टम की क्षमताओं और डिज़ाइन लक्ष्यों के भीतर है ताकि यह अन्य प्रक्रियाओं के साथ मेमोरी को पुनर्वितरित और साझा कर सके।


EDIT: अंश में उल्लिखित एक कॉपी नीचे दी गई है।

ASIDE: क्यों कोई याद नहीं है कि आपके प्रक्रिया के परिणाम हैं

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

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

मेमोरी एपीआई अध्याय के पेज 7 से

ऑपरेटिंग सिस्टम: तीन आसान मोहरे
रेम्ज़ी एच। अर्पसी-डूसो और एंड्रिया सी। अर्पेसी-डूसो अर्पसी-डूसो बुक्स मार्च, 2015 (संस्करण 0.90)


4

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

यदि प्रक्रिया अल्पकालिक है तो आप अक्सर ऐसा करने से दूर हो सकते हैं क्योंकि प्रक्रिया पूरी होने पर सभी आवंटित मेमोरी को ऑपरेटिंग सिस्टम द्वारा पुनर्प्राप्त किया जाता है, लेकिन मैं आपको उन सभी मेमोरी को मुक्त करने की आदत डालने की सलाह दूंगा जिनका आपके पास आगे कोई उपयोग नहीं है।


1
मैं आपके पहले कथन "कोई खतरा नहीं है" के लिए -1 कहना चाहता हूं, सिवाय इसके कि आप इसके बारे में एक विचारशील उत्तर दें कि आईएस का खतरा क्यों है।
डेविन बी

2
खतरों के रूप में यह बहुत सौम्य है - मैं किसी भी दिन एक segfault पर एक स्मृति रिसाव ले जाऊँगा।
काइल क्रोनिन

1
बहुत सही है, और हम दोनों ना तो = D
DevinB

2
@KyleCronin मैं एक मेमोरी रिसाव की तुलना में एक segfault ज्यादा होगा , क्योंकि दोनों गंभीर कीड़े हैं और segfaults का पता लगाना आसान है। सभी अक्सर स्मृति लीक पर किसी का ध्यान नहीं जाता है या अनसुलझे होते हैं क्योंकि वे "सुंदर सौम्य" होते हैं। मेरी राम और मैं पूरी तरह से असहमत हैं।
डैन बेहार्ड

@ एक डेवलपर के रूप में, सुनिश्चित करें। एक उपयोगकर्ता के रूप में, मैं मेमोरी लीक ले जाऊंगा। मैं बल्कि सॉफ्टवेयर है कि काम करता है, स्मृति के साथ लीक सॉफ्टवेयर के साथ काम करता है, जो नहीं करता है।
काइल क्रोनिन

3

आप उस लिहाज से बिल्कुल सही हैं। छोटे तुच्छ कार्यक्रमों में जहां प्रोग्राम की मृत्यु तक एक चर मौजूद होना चाहिए, मेमोरी से निपटने के लिए कोई वास्तविक लाभ नहीं है।

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

कहा जा रहा है, ज्यादातर कार्यक्रमों में यह वास्तव में एक विकल्प नहीं है, या यह आपको स्मृति से बाहर चलाने के लिए नेतृत्व कर सकता है।


2

आप सही हैं, प्रक्रिया से बाहर निकलने पर मेमोरी स्वचालित रूप से मुक्त हो जाती है। जब प्रक्रिया समाप्त हो जाती है, तो कुछ लोग व्यापक सफाई नहीं करने का प्रयास करते हैं, क्योंकि यह सभी ऑपरेटिंग सिस्टम से संबंधित होगा। हालाँकि, जब आपका प्रोग्राम चल रहा हो तो आपको अप्रयुक्त मेमोरी को खाली कर देना चाहिए। यदि आप ऐसा नहीं करते हैं, तो आप अंततः बाहर निकल सकते हैं या यदि आपका वर्किंग सेट बहुत बड़ा हो जाता है तो अत्यधिक पेजिंग का कारण बन सकता है।


2

यदि आप स्क्रैच से एप्लिकेशन विकसित कर रहे हैं, तो आप मुफ्त कॉल करने के बारे में कुछ शिक्षित विकल्प बना सकते हैं। आपका उदाहरण कार्यक्रम ठीक है: यह मेमोरी आवंटित करता है, हो सकता है कि आपके पास कुछ सेकंड के लिए काम हो, और फिर आपके द्वारा दावा किए गए सभी संसाधनों को मुक्त कर देता है।

यदि आप कुछ और लिख रहे हैं, हालांकि - एक सर्वर / लंबे समय से चल रहे एप्लिकेशन, या किसी अन्य व्यक्ति द्वारा उपयोग की जाने वाली लाइब्रेरी, आपको हर उस चीज़ पर मुफ्त कॉल करने की उम्मीद करनी चाहिए जो आप मॉलोक करते हैं।

एक दूसरे के लिए व्यावहारिक पक्ष की उपेक्षा, यह सख्त दृष्टिकोण का पालन करने के लिए बहुत सुरक्षित है, और अपने आप को सब कुछ मुक्त करने के लिए मजबूर करता है। जब भी आप मेमोरी कोड देखने की आदत नहीं रखते हैं, तो आप आसानी से कुछ लीक को हटा सकते हैं। तो दूसरे शब्दों में, हाँ - आप इसके बिना दूर हो सकते हैं; कृपया सावधान रहें, हालांकि।


0

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


-2

मुझे लगता है कि आपके दो उदाहरण वास्तव में केवल एक हैं: free()प्रक्रिया के अंत में ही होना चाहिए, जैसा कि आप इंगित करते हैं कि प्रक्रिया समाप्त होने के बाद से बेकार है।

हालांकि आप दूसरे उदाहरण में, एकमात्र अंतर यह है कि आप एक अपरिभाषित संख्या की अनुमति देते हैं malloc(), जिससे मेमोरी समाप्त हो सकती है। स्थिति को संभालने का एकमात्र तरीका रिटर्न कोड की जांच करना malloc()और तदनुसार कार्य करना है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.