2009-08-11 21 views
9

मेरे पास एक ऐसा कार्यक्रम है जिसमें मुझे लूप के लिए नेस्टेड के बड़े समूह से बाहर निकलने की आवश्यकता है। अब तक, जिस तरह से ज्यादातर लोग मुझे यह करने के लिए कह रहे हैं, मेरे कोड में एक बदसूरत गोटो का उपयोग करना है।गोटो कारण मेमोरी लीक का उपयोग करेगा?

अब, अगर मैं स्थानीय ढेर का एक समूह बनाने के (मुझे लगता है कि है कि वे क्या कहा जाता है यदि नहीं, तो मैं नए आदेश का उपयोग कर के बिना बस नियमित चर मतलब है) मेरी छोरों के अंदर चर और मेरा कार्यक्रम हिट है कि एक बयान है कि अगर गेटो को ट्रिगर करता है, क्या मुझे अपने प्रोग्राम के कारण कई लूपों को अनुचित तरीके से निकालने और स्थानीय चर की सफाई नहीं करने के कारण मेमोरी लीक का सामना करना पड़ेगा?

+0

आप उन ऑटो (क्या आप ढेर कहा जाता है) के साथ स्मृति लीक नहीं होगा। लेकिन कृपया गोटो का उपयोग न करें। –

+8

गोटो के साथ क्या गलत है? –

+0

संबंधित प्रश्न: http://stackoverflow.com/questions/1257744 –

उत्तर

19

नहीं, आप एक स्मृति रिसाव का कारण नहीं बनेगा ।goto का उपयोग करना "अनुचित तरीके से बाहर निकलना" नहीं है। यह केवल है जो आमतौर पर कोड-संरचना बिंदु-दृश्य से की अनुशंसा नहीं करता है।

उस तरफ, जब आप लूप छोड़ते हैं, तो स्थानीय चर स्कोप से बाहर हो जाएंगे और प्रक्रिया में ढेर (यानी साफ हो जाएंगे) से पॉप हो जाएंगे।

+0

को स्पष्ट करने के लिए कुछ और कटोरे जोड़े हैं आह हम वहां जाते हैं, धन्यवाद। – Faken

+0

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

0

नहीं आप नहीं करेंगे।

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

0

नहीं। स्थानीय चर को व्यक्तिगत रूप से साफ करने की आवश्यकता नहीं है। जब ढेर पॉप हो जाता है, तो सभी स्थानीय चर इसके साथ ही चले जाएंगे।

2

नहीं। आप गतिशील रूप से आवंटित स्मृति को केवल रिसाव कर सकते हैं।

+1

आप अन्य तरीकों से स्मृति को रिसाव कर सकते हैं। थ्रेड स्टैक पर कुछ दर्जन मेगाबाइट आवंटित करें, फिर थोड़ी देर के लिए सो जाओ, उदाहरण के लिए :) – bdonlan

+2

lol तो आपको – hobodave

+0

+1, होबोडाव शॉट किया जाना चाहिए। आप, महोदय, आज मुझे क्रैक करने वाले पहले व्यक्ति हैं। – jkeys

1

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

+0

हां, लेकिन अगर मैं किसी फ़ंक्शन का उपयोग नहीं कर रहा हूं तो क्या होगा? क्या यह भी सच है यदि मैं अपने मुख्य कार्यक्रम के अंदर एक बार में कई लूपों को तोड़ने के लिए गोटो का उपयोग करता हूं? – Faken

+0

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

+0

सी ++ और सी में आपका कोड हमेशा एक फ़ंक्शन या किसी अन्य के भीतर चल रहा है। यह कार्य निश्चित रूप से मुख्य() हो सकता है। –

1

गोटो हमेशा बुरा नहीं होता है, लेकिन आपके मामले में आपको शायद गोटो का उपयोग नहीं करना चाहिए।

गोटो here और here के अच्छे उपयोग के उदाहरण देखें।

यदि आपके पास एक लेबल है जो दायरे से बाहर है तो आपकी वस्तु को ढेर पर मुक्त कर दिया जाएगा।

उदाहरण:

#include <iostream> 
using namespace std; 

class A 
{ 
public: 
    ~A() 
    { 
    cout<<"A destructor"<<endl; 
    } 
}; 



int main(int argc, char**argv) 
{ 
    { 
    A a; 
    cout<<"Inside scope"<<endl; 
    goto l; 
    cout<<"After l goto"<<endl; 
    } 

    cout<<"Outside of scope before l label"<<endl; 

l: 
    cout<<"After l label"<<endl; 
    return 0; 
} 

यह प्रिंट होगा:

गुंजाइश
अंदर एक नाशक
एल लेबल के बाद

+0

आप सही हैं, लेकिन विनाश कॉल की समयबद्धता इस आउटपुट द्वारा नहीं दिखायी जाती है। हो सकता है कि 'एल' लेबल के आसपास कोउट जोड़ें? – xtofl

+0

@xtofl: अच्छा विचार, मैंने –

0

नहीं, आपके लूप में कोई भी स्वचालित चर प्रोग्रामिंग लीक का कारण नहीं बनता है यदि आप गोटो स्टेटमेंट के साथ अपने लूप से बाहर निकलते हैं।

1

अन्य उत्तरों सच हैं .... हालांकि, अगर आपको अलग-अलग लूप घोंसला करना है, तो मैं उन डिजाइनों पर सवाल उठाऊंगा जो उन्हें वहां रखे। उस तर्क को अलग-अलग कार्यों में विभाजित करना ऐसी समस्या को हल करने का एक बेहतर तरीका होगा।

Billy3

+0

हाँ, मैं 5 डी सरणी का उपयोग करने में भी अपने तर्क पर सवाल करता हूं, लेकिन क्या काम करता है, काम करता है। मुझे नहीं पता, पूरा कार्यक्रम शुरू करने के लिए एक विशाल पाश के रूप में शुरू होता है और यह डेटा के एक सेट पर सामान की पूरी तरह से झटके को लूपिंग करता रहता है। – Faken

+0

पवित्र ... एक ** 5 डी ** सरणी? मेरे लिए कभी भी एकमात्र औचित्य PHP में है जहां सरणी और ऑब्जेक्ट डेटा स्टोरेज उद्देश्यों के लिए भी एक ही बात हो सकती है ... गंभीरता से, आपको सी में 5 डी सरणी की क्या आवश्यकता है? –

+0

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

5

ढेर चर (ऑटो, नहीं autobots) नई के माध्यम से आवंटित चर की तरह "टपकाया" नहीं कर रहे हैं() या malloc()।

जहां तक ​​गेटोस की "बदसूरत" सिर्फ कुत्ते की तरह है। Knuth पढ़ें, वह Dijkstra के रूप में बस शानदार था। http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf पास्ता आधारित प्रोग्रामिंग से बचें, लेकिन सावधानीपूर्वक उपयोग स्पेगेटी में गिरावट नहीं आएगी।

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

समझें कि गेटोस आपका पहला समाधान नहीं होना चाहिए, और उनका उपयोग करने के लिए अपने रास्ते से बाहर नहीं जाना चाहिए, लेकिन अगर यह समझ में आता है कि यह dogmatic lench mobs को सबमिट नहीं करता है। ब्रेक स्टेटमेंट उन मामलों के लिए डिज़ाइन किया गया है जो "गेटोस का उपयोग नहीं करेंगे" आदेश का सख्ती से पालन नहीं करते थे।

+1

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

+3

ब्रेक "एकल निकास" मानदंड तोड़ता है जो डिजस्ट्रा का बहुत शौकिया था। यह आपको एक लूप के रूप में एक अच्छी तरह से संरचित निर्माण के बीच से बाहर छोड़ देता है, जिसमें एक एकल प्रविष्टि और एकल निकास होता है। व्यावहारिक मूल्यांकन के साथ एक ब्रेक का उपयोग व्यावहारिक मूल्यांकन के साथ किया जाना चाहिए। यदि गोटो स्टेटमेंट का प्रकार था डिज़ास्ट संरचित प्रोग्रामिंग द्वारा प्रतिस्थापित करना चाहता था। यदि ब्रेक समान निर्माण है जहां ब्रेक द्वारा केवल अंतर ही गोटो को प्रतिस्थापित किया गया है। ब्रेक इन मामलों के लिए गेटो से केवल मामूली बेहतर मानते हैं क्योंकि आप जहां सीमित हो सकते हैं, उसमें सीमित हैं। – NoMoreZealots

+0

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

0

पिछड़ा गेटो रिसाव संसाधन होगा? या नीचे कोड के साथ कोई अन्य संभावित समस्याएं?

Reexecute:

 try 
     { 
      //Setup request 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 

      .... 

      //Get Response 
      HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

      if(response != HttpStatus.OK && noOfRetries < 3) 
      { 
       noOfRetries++; 
       Thread.Sleep(10 * 1000); 


       response.Close(); 
       goto Reexecute; 
      } 
      ... 

      response.Close(); 
     } 
     catch 
     { 

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