2009-04-15 24 views
5

सी ++ में, मेरा मानना ​​है कि, पुनर्वितरण से निपटने का एक बेहतर तरीका एक एसटीएल वैक्टर का उपयोग करना है, क्योंकि यह संगत स्टोरेज स्थानों की गारंटी देता है।एसटीएल वेक्टर realloc का एक बेहतर संस्करण है?

  1. वहाँ किसी भी परिदृश्य जिसमें मैं realloc वेक्टर से अधिक पसंद करते हैं करने की आवश्यकता है:

    मैं अंतर को समझने के जोड़े को सवाल है?

  2. क्या कुछ और है (वेक्टर के अलावा) जो सी ++ में realloc के बराबर है?

धन्यवाद, ताकि एक कारण इसका इस्तेमाल करने के लिए नहीं नहीं है

उत्तर

14

यह केवल vector है, जो कि समेकित स्मृति की गारंटी है। दूसरों को नहीं।

realloc एक सी मेमोरी प्रबंधन फ़ंक्शन है। इसका उपयोग सी ++ कोड में प्रोत्साहित नहीं किया जाता है। यहाँ Stroustrup आपको बता रहा है क्यों: Why doesn't C++ have an equivalent to realloc()?

हालांकि, realloc() केवल() malloc द्वारा आवंटित सरणियों (और समान कार्य) पर काम करने के उपयोगकर्ता परिभाषित प्रति कंस्ट्रक्टर्स बिना वस्तुओं युक्त गारंटी है। साथ ही, कृपया याद रखें कि निष्पक्ष उम्मीदों के विपरीत, realloc() कभी-कभी इसकी तर्क सरणी की प्रतिलिपि बनाता है।

+1

realloc पीओडी प्रकारों के अलावा कुछ भी काम नहीं करेगा, क्योंकि यह रचनाकारों/विनाशकों के बारे में नहीं जानता है। – lothar

+0

वेक्टर के पास मॉलोक की स्मृति पर भी लाभ होता है, जब वे गुंजाइश से बाहर निकलते हैं तो उन्हें हटा दिया जाएगा, इस प्रकार अपवादों को फेंकने पर मेमोरी लीक कम हो जाती है, जब आप स्मृति को मुक्त करना भूल जाते हैं, आदि –

+0

@ डिर्कर्जली टूटा लिंक, कर सकते हैं आप कृपया अपडेट करें? –

8

क्रमिक मेमोरी भी realloc द्वारा की गारंटी है।

हालांकि, मैं सी ++ में वेक्टर का उपयोग करना पसंद करूंगा क्योंकि यह उच्च स्तर के अमूर्तता पर है, इसलिए यह कोड को लिखना आसान बनाता है।

एक सरणी प्रकार के परिदृश्य के लिए रीयलोक (वेक्टर पर) का उपयोग करने के लिए एकमात्र संभावित कारण है, कच्ची गति है। यह तेज हो सकता है। और मैं "मई" शब्द पर जोर देता हूं - माप, अनुमान मत लगाओ!

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

1

मुझे लगता है कि यह केवल एक वेक्टर है।

मैंने किसी को भी नहीं देखा है जो सी ++ में रीयलोक का उपयोग करने का सुझाव देगा।

10

सी कार्यों का सेट (मॉलोक, कॉलोक, रीयलोक, फ्री) कच्चे मेमोरी ऑपरेशंस हैं। वे स्मृति में दिए गए बफर को बना/संशोधित/रिलीज़ करेंगे, लेकिन स्मृति में कोई प्रकार नहीं होगा और कोई कन्स्ट्रक्टर नहीं कहा जाएगा।

सी ++ realloc के समतुल्य नहीं है, लेकिन/के उपयोग के माध्यम मुक्त malloc के लिए केवल typesafe समकक्ष नई/नई [] और हटाने/[] को हटा दें। सी ++ संस्करण दोनों उपयुक्त रचनाकारों को कॉल करके सिस्टम और से स्मृति प्राप्त करेंगे। का उपयोग हटाएं ऑब्जेक्ट्स के विनाशकों को कॉल करेगा और फिर स्मृति को रिलीज़ करेगा।C और C++ संस्करण यदि आप malloc (भले ही आप प्राप्त स्मृति पर inplace निर्माता कहते हैं) आप हटाना [] के रूप में यह अपरिभाषित व्यवहार है साथ इसे जारी नहीं कर सकते/हटा के साथ स्मृति के अधिग्रहण, संगत नहीं हैं।

सी ++ में realloc का उपयोग असुरक्षित हो सकता है, क्योंकि यह वस्तुओं को एक मेमोरी क्षेत्र से अगले में कॉपी करेगा। कभी-कभी आपकी ऑब्जेक्ट्स मेमोरी चाल के साथ ठीक से सौदा नहीं करती हैं (कहें कि आपके ऑब्जेक्ट में एक विशेषता और इसका संदर्भ है, बिटवॉइस इसे संदर्भित करने के बाद संदर्भ वास्तविक विशेषता के बजाए पुरानी स्थिति को इंगित करेगा)। वेक्टर के अंदर, जब भी स्मृति को बढ़ने की आवश्यकता होती है, तो नए [] के साथ एक नई मेमोरी अधिग्रहित की जाती है और फिर पुराने तत्वों को हटाने से पहले उपयुक्त सी ++ संचालन का उपयोग करके सभी ऑब्जेक्ट्स प्रतिलिपि (या प्रतिलिपि बनाई गई) होती हैं।

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

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

+1

वेक्टर v.shrink_to_fit() को कॉल करते समय, आकार को कम नहीं करते हैं, जो C++ 11 में नया है। ध्यान दें कि एक कार्यान्वयन कॉल को अनदेखा करना चुन सकता है। – MaHuJa

+0

@ माहुजा: 'std :: वेक्टर (myVector) .swap (myVector); 'सभी कार्यान्वयन में मैं जानता हूं (अनिवार्य नहीं) वेक्टर को उचित आकार में छोटा कर दें। –

5

std :: वेक्टर के मुख्य लाभों में से एक यह है कि जब यह स्वाभाविक रूप से बढ़ते हुए आंतरिक रूप से आंतरिक रूप से पुन: स्थापित होता है, तो यह आकार का आकार चुनता है जो वर्तमान आकार (आमतौर पर - लेकिन हमेशा एक स्थिर गुणक) से 2x बड़ा होता है। इसका मतलब है कि push_back ने ओ (1) लागत को अमूर्त किया है।

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

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