सी ++ में, स्टैक का उपयोग करना सबसे अच्छा कब है? ढेर का उपयोग करना सबसे अच्छा कब है?ढेर के बजाय ढेर का उपयोग करना सबसे अच्छा है और इसके विपरीत?
उत्तर
स्टैक का उपयोग करें जब वर्तमान चर रिटर्न के बाद आपके चर का उपयोग नहीं किया जाएगा। वर्तमान कार्य के जीवनकाल से परे चर में डेटा की आवश्यकता होने पर ढेर का उपयोग करें।
हालांकि इसके आसपास जाने के तरीके हैं। एक फ़ंक्शन को एक बफर पास करना जो उसके बाद डेटा लिखता है, एक फंक्शन "रिटर्न" गतिशील डेटा रखने का एक अच्छा तरीका है जो कम स्टैक फ्रेम में रहता है। यह ओओ की तरह कम है, लेकिन यह अधिक कुशल है। –
आकार भी एक विचार है: ढेर पर 1K से अधिक कुछ सावधानी से विचार किया जाना चाहिए। कभी-कभी स्मृति को ढेर करने के लिए एक स्टैक पॉइंटर होना बेहतर होता है (साथ ही 'रिसोर्स अधिग्रहण प्रारंभिक' idiom के साथ) – Arkadiy
लेकिन जब स्मृति कक्षा की संपत्ति होती है, तो आप कैसे निर्णय लेते हैं कि क्लास प्रॉपर्टी पॉइंटर या अन्यथा कब होनी चाहिए? इसके अलावा आप एक स्मार्ट सूचक का उपयोग कब कर सकते हैं? – JagWire
रनटाइम पर ऑब्जेक्ट्स के लिए केवल स्थान आवंटित करने के लिए ढेर का उपयोग करें। यदि आप संकलन समय पर आकार जानते हैं, तो स्टैक का उपयोग करें। किसी फ़ंक्शन से ढेर-आवंटित वस्तुओं को वापस करने के बजाय, इसे लिखने के लिए फ़ंक्शन में एक बफर पास करें। इस तरह बफर को आवंटित किया जा सकता है जहां फ़ंक्शन को सरणी या अन्य स्टैक-आधारित संरचना कहा जाता है।
आपके पास कम मॉलोक() कथन है, मेमोरी लीक के लिए कम संभावनाएं हैं।
यह प्रश्न संबंधित है (हालांकि वास्तव में एक डुप्ली नहीं) What and where are the stack and heap पर, जिसे कुछ दिन पहले पूछा गया था।
प्रश्न बीमार गठित है।
ऐसी स्थितियां हैं जहां आपको ढेर की आवश्यकता होती है, अन्य जहां आपको ढेर की आवश्यकता होती है, अन्य जहां आपको स्थिर भंडारण की आवश्यकता होती है, अन्य जहां आपको कॉन्स मेमोरी डेटा की आवश्यकता होती है, अन्य जहां आपको मुफ्त स्टोर की आवश्यकता होती है।
ढेर तेजी से है, क्योंकि आवंटन एसपी पर सिर्फ "वृद्धि" है, और सभी "आवंटन" आपके द्वारा किए गए फ़ंक्शन के आमंत्रण समय पर किया जाता है। हीप (या फ्री स्टोर) आवंटन/डेलोकेशन अधिक समय होता है महंगा और त्रुटि प्रवण।
अंगूठे के नियम के रूप में, ढेर पर विशाल वस्तुओं को बनाने से बचें।
- स्टैक पर एक ऑब्जेक्ट बनाना आपको ऑब्जेक्ट को क्लीनअप (हटाएं) को याद रखने के बोझ से मुक्त करता है। लेकिन ढेर पर बहुत सारी वस्तुओं को बनाने से ढेर अतिप्रवाह की संभावना बढ़ जाएगी।
- यदि आप ऑब्जेक्ट के लिए ढेर का उपयोग करते हैं, तो आपको ओएस प्रदान की जा सकने वाली उतनी ही मेमोरी मिलती है, जो स्टैक से काफी बड़ी है, लेकिन फिर आपको यह सुनिश्चित करना होगा कि जब आप पूरा कर लें तो स्मृति को मुक्त करना होगा। इसके अलावा, ढेर में बहुत अधिक ऑब्जेक्ट्स बनाना अक्सर स्मृति को खंडित करता है, जो बदले में आपके आवेदन के प्रदर्शन को प्रभावित करेगा।
स्टैक का उपयोग करें जब स्मृति का उपयोग किया जा रहा है, उस क्षेत्र तक सख्ती से सीमित है जिसमें आप इसे बना रहे हैं। यह स्मृति रिसाव से बचने के लिए उपयोगी है क्योंकि आप जानते हैं कि आप स्मृति का उपयोग कहां करना चाहते हैं, और आपको पता है कि आपको इसकी आवश्यकता नहीं है, इसलिए स्मृति आपके लिए साफ हो जाएगी।
int main()
{
if (...)
{
int i = 0;
}
// I know that i is no longer needed here, so declaring i in the above block
// limits the scope appropriately
}
ढेर, तथापि, जब अपनी स्मृति इसके निर्माण के दायरे से बाहर पहुँचा जा सकता है और आप एक ढेर चर नकल करने की इच्छा नहीं उपयोगी है। यह आपको स्पष्ट नियंत्रण दे सकता है कि स्मृति आवंटित और अस्वीकृत कैसे किया जाता है।
Object* CreateObject();
int main()
{
Object* obj = CreateObject();
// I can continue to manipulate object and I decide when I'm done with it
// ..
// I'm done
delete obj;
// .. keep going if you wish
return 0;
}
Object* CreateObject()
{
Object* returnValue = new Object();
// ... do a bunch of stuff to returnValue
return returnValue;
// Note the object created via new here doesn't go away, its passed back using
// a pointer
}
स्पष्ट रूप से यहां एक आम समस्या यह है कि आप अपनी वस्तु को हटाना भूल सकते हैं। इसे मेमोरी रिसाव कहा जाता है। ये समस्याएं अधिक प्रचलित हैं क्योंकि आपका प्रोग्राम कम और कम छोटा हो जाता है जहां "स्वामित्व" (या चीजों को हटाने के लिए वास्तव में कौन जिम्मेदार है) परिभाषित करना अधिक कठिन हो जाता है।
अधिक प्रबंधित भाषाओं (सी #, जावा) में सामान्य समाधान कचरा संग्रहण लागू करना है ताकि आपको चीजों को हटाने के बारे में सोचना न पड़े।हालांकि, इसका मतलब है पृष्ठभूमि में कुछ ऐसा है जो आपके ढेर डेटा को जांचने के लिए aperiodically चलाता है। एक गैर-तुच्छ कार्यक्रम में, यह "कचरा संग्रह" धागा पॉप अप हो जाता है और चग्स के रूप में बल्कि अक्षम हो सकता है, हटाए जाने वाले डेटा की तलाश में, जबकि आपका शेष प्रोग्राम निष्पादित करने से अवरुद्ध हो जाता है।
सी ++ में, स्मृति लीक से निपटने के लिए सबसे आम, और सर्वोत्तम (मेरी राय में) समाधान एक स्मार्ट सूचक का उपयोग करना है। इनमें से सबसे आम boost::shared_ptr जो है (reference counted)
तो ऊपर बढ़ावा :: shared_ptr CreateObject उदाहरण बनाना() है;
int main()
{
boost::shared_ptr<Object> obj = CreateObject();
// I can continue to manipulate object and I decide when I'm done with it
// ..
// I'm done, manually delete
obj.reset(NULL);
// .. keep going if you wish
// here, if you forget to delete obj, the shared_ptr's destructor will note
// that if no other shared_ptr's point to this memory
// it will automatically get deleted.
return 0;
}
boost::shared_ptr<Object> CreateObject()
{
boost::shared_ptr<Object> returnValue(new Object());
// ... do a bunch of stuff to returnValue
return returnValue;
// Note the object created via new here doesn't go away, its passed back to
// the receiving shared_ptr, shared_ptr knows that another reference exists
// to this memory, so it shouldn't delete the memory
}
और फिर वहां चलने वाले अर्थ थे –
अंगूठे के नियम के रूप में जब भी आप कर सकते हैं स्टैक का उपयोग करें। यानी जब उस दायरे के बाहर परिवर्तनीय की आवश्यकता नहीं होती है।
इसकी तेज़ी से, कम विखंडन का कारण बनता है और कॉलिंग मॉलोक या नए से जुड़े अन्य ओवरहेड से बचने जा रहा है। ढेर से आवंटित करना एक असेंबलर ऑपरेशंस का एक जोड़ा है, मॉलोक या नया एक कुशल कार्यान्वयन में कोड की कई सौ रेखाएं हैं।
यह ढेर का उपयोग करने के लिए कभी भी सबसे अच्छा नहीं है ... बस अपरिहार्य है। :)
यह कुछ असेंबलर ऑपरेशंस से बेहतर है - यह केवल एक जोड़ या घटाना है (इस आधार पर कि आपका स्टैक किस दिशा में बढ़ता है)। – Eclipse
जोड़ता है और घटाव हमेशा एकल ओप नहीं होते हैं ... लेकिन दूसरे छोर पर साफ-सफाई पर भी विचार करते हैं। कॉल कन्वेंशन के आधार पर ऐड/सब से मेल खाने के लिए एक उप/ऐड होने जा रहा है, हालांकि इन सभी को समेकित किया जा सकता है कि आप कैसे स्टैक का उपयोग करते हैं और संकलक क्या अनुकूलन करता है (यह वास्तव में शून्य निर्देशों तक उबाल सकता है। .. या बहुत विशेष मामलों में, ऋण निर्देश) – jheriko
नियम यह है कि ऊपर उल्लेख किया है आप स्थानीय चर कि समारोह के दायरे से बाहर की जरूरत नहीं कर रहे हैं के लिए ढेर का उपयोग आम तौर पर करना चाहिए के लिए एक अपवाद:
रिकर्सिव कार्यों ढेर अंतरिक्ष निकास सकता है अगर वे बड़े स्थानीय आवंटित चर या यदि उन्हें कई बार बार-बार बुलाया जाता है। यदि आपके पास स्मृति का उपयोग करने वाला एक पुनरावर्ती फ़ंक्शन है, तो स्टैक-आधारित मेमोरी के बजाय हीप-आधारित मेमोरी का उपयोग करना एक अच्छा विचार हो सकता है।
- 1. ढेर ढेर और ढेर
- 2. सी ++ में उचित ढेर और ढेर उपयोग?
- 3. ढेर और ढेर आवंटन
- 4. एक ढेर और ढेर क्यों है?
- 5. विंडोज असेंबली ढेर और ढेर?
- 6. ढेर सी ++
- 7. ढेर
- 8. आप ढेर के बजाय ढेर पर स्मृति आवंटित क्यों करना चाहते हैं?
- 9. क्लोजर में, हम मैक्रो और इसके विपरीत के बजाय एक मोनड का उपयोग कब करना चाहिए?
- 10. ढेर
- 11. ढेर और ढेर पर स्मृति स्थान पैटर्न
- 12. मुझे विरासत के बजाय टेम्पलेट का उपयोग कब करना चाहिए, और इसके विपरीत?
- 13. वाल्ग्रिंड का उपयोग कर सी में फ़ंक्शन के ढेर और ढेर के उपयोग को कैसे देखें?
- 14. मुझे एनएसएसटींग के बजाय NSRL का उपयोग कब करना चाहिए और इसके विपरीत?
- 15. सी ++ ढेर और ढेर पर स्मृति आवंटित?
- 16. ढेर
- 17. सी चर और ढेर चर ढेर ++
- 18. ढेर और कतार, क्यों?
- 19. जावा ढेर और ढेर स्मृति आवंटन
- 20. ढेर वास्तव में एक ढेर है?
- 21. libGL ढेर उपयोग
- 22. क्या होता है जब ढेर और ढेर कोलाइड
- 23. नेट ढेर बनाम विंडोज ढेर
- 24. ढेर/ढेर पर कक्षा के सदस्यों का आवंटन?
- 25. मुझे PHP (या इसके विपरीत) के बजाय पर्ल सीजीआई का उपयोग कब करना चाहिए?
- 26. ढेर अतिप्रवाह और कीवर्ड
- 27. सी # structs/वर्ग ढेर/ढेर नियंत्रण?
- 28. "ए" ढेर और "द" ढेर के बीच का रिश्ता क्या है?
- 29. जावा में स्थिर आवंटन - ढेर, ढेर और स्थायी पीढ़ी
- 30. एक फाइबोनैकी ढेर क्यों एक फाइबोनैकी ढेर कहा जाता है?
मुझे लगता है कि आप स्मृति संरचना आवंटित करने के लिए सिस्टम ढेर और सिस्टम ढेर का मतलब है, डेटा संरचना ढेर और ढेर नहीं, सही? –