[Powered by Google Translate] [वेलग्रिंड] [नैट Hardison, हार्वर्ड विश्वविद्यालय] इस CS50 है, CS50.TV] सी कार्यक्रमों में सबसे कठिन कीड़े के कुछ स्मृति के कुप्रबंधन से आते हैं. बातें पेंच के तरीके की एक बड़ी संख्या है, स्मृति के गलत राशि का आवंटन भी शामिल है, चर इनिशियलाइज़ भूल, एक बफर के अंत से पहले या बाद में लेखन, मुक्त और स्मृति कई बार रखना. लक्षण आंतरायिक दुर्घटनाओं से लेकर को अधिलेखित कर दिया मूल्यों के लिए रहस्यमय तरीके से, अक्सर स्थानों और समय तक मूल त्रुटि से हटा. मनाया समस्या वापस अनुरेखण अंतर्निहित जड़ चुनौतीपूर्ण हो सकता है, लेकिन सौभाग्य से वहाँ एक उपयोगी कार्यक्रम वेलग्रिंड बुलाया है कि एक बहुत कुछ करने के लिए मदद कर सकते हैं. आप वेलग्रिंड के तहत एक कार्यक्रम चलाने करने के लिए सक्षम ढेर स्मृति आवंटन और accesses के व्यापक जाँच. जब वेलग्रिंड एक समस्या का पता लगाता है, यह आप तत्काल देता है, प्रत्यक्ष जानकारी है कि आप के लिए अनुमति देता है और अधिक आसानी से खोजने के लिए और समस्या को ठीक. भी कम घातक स्मृति के मुद्दों पर रिपोर्ट वेलग्रिंड, जैसे स्मृति लीक, ढेर स्मृति आवंटन और इसे मुफ्त भूल. हमारे debugger में हमारे संकलक बजना, GDB की तरह, वेलग्रिंड मुफ्त सॉफ्टवेयर है, और यह उपकरण पर स्थापित है. वेलग्रिंड अपने द्विआधारी निष्पादन पर चलाता है, या नहीं, आपके ग ज. स्रोत कोड फ़ाइलें, तो सुनिश्चित करें कि आप अपने कार्यक्रम की एक प्रतिलिपि अप तारीख संकलित किया है बजना का उपयोग कर या बनाओ. फिर, वेलग्रिंड के तहत अपने कार्यक्रम चल रहा हो सकता है सिर्फ शब्द मेजबान पर चल साथ मानक कार्यक्रम कमांड prefixing के रूप में सरल, जो शुरू होता है वेलग्रिंड और इसे के अंदर कार्यक्रम चलाता है. जब शुरू, वेलग्रिंड कुछ जटिल करता है स्मृति की जाँच के लिए निष्पादन कॉन्फ़िगर jiggering, तो यह थोड़ा लेने के लिए और चलाने के लिए कर सकते हैं. कार्यक्रम तो सामान्य रूप से निष्पादित, यह हो सकता है और अधिक धीरे धीरे, और जब यह खत्म, वेलग्रिंड अपनी स्मृति के उपयोग का एक सारांश मुद्रित होगा. यदि सब कुछ ठीक हो जाता है, तो यह कुछ इस तरह दिखेगा: इस मामले में, / clean_program कार्यक्रम मैं चलाने के लिए करना चाहते हैं के लिए रास्ता है. और जब यह एक किसी भी तर्क नहीं है, अगर यह था कि मैं सामान्य रूप से आदेश का अंत करने के लिए सिर्फ उन्हें कील था. स्वच्छ कार्यक्रम सिर्फ एक मूर्ख थोड़ा कार्यक्रम मैंने बनाया है कि ढेर पर ints की एक ब्लॉक के लिए अंतरिक्ष का आवंटन, उनमें से अंदर कुछ मूल्यों डाल, और पूरे ब्लॉक को मुक्त कर देते. यह है कि क्या आप के लिए शूटिंग कर रहे हैं, कोई त्रुटि है और कोई लीक. एक अन्य महत्वपूर्ण मीट्रिक आवंटित बाइट्स की कुल संख्या है. कार्यक्रम पर निर्भर करता है, अगर अपने आवंटन मेगाबाइट या उच्च में हैं, आप शायद कुछ गलत कर रहे हैं. तुम बेकार में डुप्लिकेट भंडारण? क्या आप भंडारण के लिए ढेर का उपयोग कर रहा है, जब यह बेहतर होगा ढेर प्रयोग करेंगे? तो, मेमोरी त्रुटियों को सही मायने में बुराई हो सकता है. अधिक प्रकट वाले शानदार दुर्घटनाओं का कारण, लेकिन फिर भी यह अभी भी इंगित करने के लिए मुश्किल हो सकता है क्या वास्तव में दुर्घटना के लिए नेतृत्व किया. अधिक सकपट, एक स्मृति त्रुटि के साथ एक कार्यक्रम अभी भी सफाई से संकलन कर सकते हैं और अभी भी सही ढंग से काम करने लग सकता है क्योंकि तुम समय की सबसे भाग्यशाली पाने में कामयाब रहे. कई के बाद, "" सफल परिणाम आपको लगता है कि एक दुर्घटना कंप्यूटर के एक अस्थायी है हो सकता है, लेकिन कंप्यूटर कभी भी गलत नहीं है. मेजबान पर चल रनिंग मदद कर सकते हैं कि आप नीचे दिखाई स्मृति त्रुटियों के कारण ट्रैक के रूप में अच्छी तरह के रूप में त्रुटियों गुप्त खोजने के लिए आप के बारे में भी अभी तक पता नहीं है. हर समय वेलग्रिंड एक समस्या का पता लगाता है, यह क्या देखा के बारे में जानकारी प्रिंट. प्रत्येक आइटम काफी संक्षिप्त है - हमलावर अनुदेश के स्रोत रेखा क्या मुद्दा है,, और शामिल स्मृति के बारे में एक छोटी सी जानकारी - लेकिन अक्सर यह पर्याप्त जानकारी के लिए सही जगह के लिए आपका ध्यान प्रत्यक्ष है. यहाँ वेलग्रिंड का एक उदाहरण है एक छोटी गाड़ी कार्यक्रम पर चल रहा है कि ढेर स्मृति के एक अवैध पढ़ा करता है. हम संकलन में कोई त्रुटि या चेतावनी को देखते हैं. ओह, त्रुटि सारांश का कहना है कि वहाँ दो त्रुटियाँ हैं - 4 आकार के दो अवैध पढ़ता बाइट -, कि है. दोनों बुरा पढ़ता invalid_read.c के मुख्य समारोह में हुई, 16 लाइन और 19 लाइन पर 2 पर 1. चलो कोड को देखो. 1 के लिए printf हमारी स्मृति ब्लॉक के अंत पिछले एक int पढ़ने की कोशिश करता है कॉल की तरह लग रहा है. यदि हम वेलग्रिंड उत्पादन में वापस देखो, हम देखते हैं कि वेलग्रिंड हमें पता चलता है कि वास्तव में बताया. हम पता करने के लिए पढ़ने की कोशिश कर रहे हैं 0 बाइट्स शुरू पिछले 16 बाइट आकार के ब्लॉक के अंत - चार 32-bit ints है कि हम आवंटित. यही है, पता हम पढ़ने की कोशिश कर रहे थे हमारे ब्लॉक के अंत में शुरू होता है, बस के रूप में हम हमारे बुरा printf कॉल में देखते हैं. अब, अमान्य पढ़ता है जैसे कि एक समझौते के बड़ा नहीं लग सकता है, लेकिन अगर आपको लगता है कि डेटा का उपयोग कर रहे हैं अपने कार्यक्रम के प्रवाह को नियंत्रित उदाहरण के लिए, एक के हिस्से के रूप में अगर बयान या पाश - फिर बातें चुपचाप बुरा जा सकते हैं. देखो कैसे मैं invalid_read कार्यक्रम चला सकते हैं और कुछ भी नहीं है कि साधारण से बाहर होता है. डरावना, हुह? अब, चलो त्रुटियों के कुछ प्रकार है कि आप अपने कोड में मुठभेड़ हो सकता है पर देखो, और हम देखेंगे कि मेजबान पर चल उन्हें कैसे पता लगाता है. हम सिर्फ एक invalid_read की एक उदाहरण देखा है, तो अब चलो एक invalid_write. फिर, संकलन में कोई त्रुटि या चेतावनी. ठीक है, वेलग्रिंड का कहना है कि इस कार्यक्रम में दो त्रुटियाँ हैं - और invalid_write और एक invalid_read. चलो इस कोड की जाँच करें. लगता है जैसे हम क्लासिक strlen प्लस एक बग का एक उदाहरण मिल गया है. कोड malloc अंतरिक्ष के एक अतिरिक्त बाइट नहीं है 0 / चरित्र के लिए, इसलिए जब str प्रतिलिपि यह ssubstrlen में लिखने के लिए चला गया "CS50 चट्टानों!" यह हमारी ब्लॉक के अंत पिछले 1 बाइट लिखा था. invalid_read आता है जब हम printf हमारे कॉल करते हैं. Printf अमान्य स्मृति पढ़ने समाप्त होता है जब यह / 0 चरित्र पढ़ता के रूप में यह इस ई स्ट्रिंग के अंत में लग रहा है यह मुद्रण है. लेकिन इस बात का कोई भी मेजबान पर चल भाग निकले. हम str प्रतिलिपि का हिस्सा के रूप में देखते हैं है कि यह invalid_write पकड़ा मुख्य के 11 लाइन पर, और invalid_read printf का हिस्सा है. पर रॉक, वेलग्रिंड. फिर, यह एक बड़ा सौदा की तरह प्रतीत नहीं हो सकता है. वेलग्रिंड के बाहर इस प्रोग्राम चला सकते हैं हम और अधिक से अधिक देखने के लिए और किसी भी त्रुटि के लक्षण नहीं है. हालांकि, इस बात का एक मामूली बदलाव को देखने के लिए चीजें बहुत खराब कैसे प्राप्त कर सकते हैं. तो दी, हम चीजों को कोस रहे हैं तो बस इस कोड में एक बिट से अधिक. हम ढेर पर ही कर रहे हैं, दो तार के लिए अंतरिक्ष का आवंटन CS50 चट्टानों की लंबाई, इस समय, 0 / चरित्र को याद. लेकिन फिर हम स्मृति ब्लॉक में एक सुपर लंबे स्ट्रिंग में फेंक एस की ओर इशारा करते है. क्या प्रभाव है कि स्मृति ब्लॉक पर होगा कि करने के लिए टी अंक? वैसे, अगर स्मृति टी कहते हैं कि सिर्फ एस के लिए आसन्न है, यह बस के बाद आ रहा है, तो हम टी. भाग पर लिखा है हो सकता है चलो इस कोड को चलाने. क्या हुआ देखो. तार हम हमारे ढेर दोनों ब्लॉकों में संग्रहीत करने के लिए बाहर मुद्रित है सही ढंग से दिखाई दिया. सभी में कुछ भी गलत नहीं लगता है. हालांकि, हमारे कोड में वापस जाने के लिए और बाहर लाइन टिप्पणी जहाँ हम CS50 चट्टानों की प्रतिलिपि 2 स्मृति ब्लॉक में, टी द्वारा की ओर इशारा किया. अब, जब हम इस कोड को चलाने हम चाहिए केवल देखने के लिए पहली स्मृति ब्लॉक की सामग्री मुद्रित करने के लिए. वाह, भले ही हम str कॉपी नहीं किया 2 ढेर ब्लॉक में कोई भी वर्ण, एक टी द्वारा की ओर इशारा किया, हम एक प्रिंट बाहर निकालो. दरअसल, स्ट्रिंग हम हमारे 1 ब्लॉक में भरवां 1 और 2 ब्लॉक में ब्लॉक overran, जिससे सब कुछ सामान्य लग रहे हैं. मेजबान पर चल रहा है, हालांकि, हमें सच्ची कहानी बताता है. हम वहाँ जाते हैं. उन अमान्य पढ़ता और लिखता है. चलो त्रुटि का एक और प्रकार का एक उदाहरण देखते हैं. यहाँ हम कुछ बल्कि यह दुर्भाग्यपूर्ण है. हम ढेर पर एक int के लिए अंतरिक्ष ले लो, पी - उस स्थान को इंगित करने के लिए और हम एक int सूचक इनिशियलाइज़. हालांकि, जबकि हमारे सूचक initialized है, डेटा है कि यह की ओर इशारा करते है बस कबाड़ ढेर के उस हिस्से में जो कुछ भी है. इसलिए, जब हम int i में है कि डेटा लोड हम तकनीकी रूप से मैं प्रारंभिकीकरण लेकिन हम कबाड़ डेटा के साथ ऐसा करते हैं. कॉल जोर है, जो एक आसान debugging मैक्रो पुस्तकालय aptly नाम जोर में परिभाषित किया गया है, गर्भपात कार्यक्रम अगर अपने परीक्षण हालत में विफल रहता है. यही है, अगर मैं 0 नहीं है. ढेर अंतरिक्ष में क्या था पर निर्भर करता है, पी द्वारा की ओर इशारा किया, इस कार्यक्रम कभी कभी काम और अन्य समय में असफल हो सकता है. अगर यह काम करता है, हम सिर्फ भाग्यशाली हो रही है. संकलक इस त्रुटि पकड़ नहीं है, लेकिन यकीन है कि इच्छा वेलग्रिंड होगा. वहाँ हम हमारे कि जंक डेटा के उपयोग से stemming त्रुटि देखते. जब आप ढेर स्मृति आवंटित लेकिन deallocate या नहीं यह मुक्त कि एक रिसाव कहा जाता है. एक छोटी सी, अल्पकालिक कार्यक्रम चलाता है और तुरंत बाहर निकलता है, लीक काफी हानिरहित हैं, लेकिन बड़े आकार और / या दीर्घायु की एक परियोजना के लिए, यहां तक ​​कि एक छोटी सी दरार कुछ प्रमुख में यौगिक कर सकते हैं. CS50 के लिए, हम आप के लिए उम्मीद है ढेर स्मृति है कि आप आवंटित की सभी मुक्त का ख्याल रखना, के बाद से हम आप कौशल का निर्माण करने के लिए ठीक से मैनुअल प्रक्रिया संभाल करना चाहते हैं सी. द्वारा आवश्यक ऐसा करने के लिए, अपने प्रोग्राम एक सटीक होना चाहिए malloc और मुक्त कॉल के बीच एक से एक पत्राचार. सौभाग्य से, वेलग्रिंड स्मृति लीक के साथ आप भी मदद कर सकते हैं. यहाँ एक टपकाया leak.c कार्यक्रम बुलाया है कि का आवंटन अंतरिक्ष ढेर पर, यह करने के लिए लिखते हैं, लेकिन यह मुक्त नहीं है. हम यह बनाओ और यह वेलग्रिंड के तहत चलाने के साथ संकलित, और हम देखते हैं, जब तक हम कोई स्मृति त्रुटियों है कि, हम एक दरार है. 16 बाइट्स निश्चित रूप से खो रहे हैं, जिसका अर्थ है कि कि स्मृति के लिए सूचक दायरे में नहीं था, जब इस कार्यक्रम से बाहर निकल गया. अब, हमें वेलग्रिंड रिसाव के बारे में जानकारी का एक टन नहीं दे करता है, लेकिन अगर हम इस छोटे नोट का पालन करें कि यह अपनी रिपोर्ट के नीचे की ओर नीचे देता है के साथ फिर से दौड़ना - रिसाव की जांच पूरी = लीक स्मृति के पूर्ण विवरण देखने के लिए, हम और अधिक जानकारी प्राप्त करेंगे. अब, ढेर सारांश में, वेलग्रिंड हमें बताता है, जहां स्मृति खो गया था कि शुरू में आवंटित किया गया था. बस के रूप में हम स्रोत कोड में देखने से पता वेलग्रिंड हमें बताते हैं कि हम स्मृति लीक leak.c की 8 लाइन पर malloc के लिए एक फोन के साथ आवंटित मुख्य समारोह में. सुंदर गंधा. वेलग्रिंड categorizes लीक इन शब्दों का प्रयोग: निश्चित रूप से खो - यह ढेर आवंटित स्मृति है जो कार्यक्रम अब एक सूचक है. वेलग्रिंड जानता है कि आप एक बार सूचक था लेकिन बाद में इसे का ट्रैक खो दिया. इस स्मृति को निश्चित रूप से लीक है. परोक्ष रूप से खो - यह ढेर आवंटित स्मृति है जो यह करने के लिए केवल संकेत भी खो रहे हैं. उदाहरण के लिए, यदि आप एक लिंक सूची के पहले नोड के लिए अपने सूचक को खो दिया है, तो पहला नोड ही निश्चित रूप से खो जाएगा, जबकि किसी भी बाद नोड्स परोक्ष रूप से खो जाएगा. संभवत: खो - यह ढेर आवंटित स्मृति है जो वेलग्रिंड यकीन है कि वहाँ एक सूचक है या नहीं है नहीं हो सकता. अभी भी पहुँच से बाहर ढेर आवंटित स्मृति है जो कार्यक्रम अभी भी बाहर निकलने पर एक सूचक है, जो आम तौर पर इसका मतलब है कि यह एक वैश्विक चर अंक. इन लीक की जांच करने के लिए, आप भी विकल्प शामिल होगा - अभी भी पहुँच से बाहर = हाँ वेलग्रिंड के अपने मंगलाचरण में. इन अलग अलग मामलों में उन्हें सफाई के लिए अलग रणनीति की आवश्यकता हो सकती है, लेकिन लीक समाप्त किया जाना चाहिए. दुर्भाग्य से, लीक फिक्सिंग करने के लिए कठिन हो सकता है, के बाद से मुक्त करने के लिए गलत कॉल के अपने कार्यक्रम को उड़ा सकते हैं. उदाहरण के लिए, अगर हम invalid_free.c में देखो, हम बुरा स्मृति deallocation का एक उदाहरण देखते हैं. क्या एक एकल कॉल करने के लिए पूरे ब्लॉक मुक्त होना चाहिए int_block द्वारा स्मृति के की ओर इशारा किया, बजाय एक int आकार के लिए प्रत्येक अनुभाग को मुक्त करने की कोशिश हो व्यक्तिगत रूप से स्मृति की. यह catastrophically असफल हो जायेगी. बूम! क्या एक त्रुटि है. यह निश्चित रूप से अच्छा नहीं है. यदि आप इस तरह की त्रुटि के साथ फंस रहे हैं, हालांकि, और आप देखने के लिए पता नहीं कहाँ से, अपने सर्वश्रेष्ठ नए दोस्त पर वापस आते हैं. आप यह अनुमान लगाया - वेलग्रिंड. वेलग्रिंड, हमेशा की तरह जानता है, वास्तव में क्या हो रहा है. alloc और मुक्त मायने रखता मेल नहीं खाते. हम 1 alloc और 4 को मुक्त कर देते मिल गया है. और वेलग्रिंड भी हमें बताता है जहां 1 बुरा मुफ्त कॉल - एक कि विस्फोट ट्रिगर से आ रही है - 16 लाइन. जैसा कि आप देख, बुरा को मुफ्त फोन वास्तव में खराब कर रहे हैं, तो हम अपने कार्यक्रम रिसाव दे की सिफारिश जब आप कार्यक्षमता सही हो रही पर काम कर रहे हैं. लीक के लिए तलाश शुरू होने के बाद ही अपने कार्यक्रम ठीक से काम कर रहा है, किसी भी अन्य त्रुटियों के बिना. और कहा कि हम सभी इस वीडियो के लिए मिल गया है. अब आप के लिए क्या कर रहे हैं? जाओ अपने कार्यक्रमों पर अभी वेलग्रिंड चलाने के. मेरा नाम नैट Hardison है. यह CS50 है. [CS50.TV]