2009-10-21 7 views
8

मैं विभिन्न मेमोरी रिक्त स्थान प्रबंधित करने के लिए एक एसटीएल कस्टम आवंटक वर्ग के विभिन्न उदाहरणों का उपयोग करना चाहता हूं, और उसके बाद एक एसटीएल कंटेनर को आवंटन उदाहरण निर्दिष्ट करने में सक्षम होना चाहिए जैसे प्रत्येक कंटेनर केवल खींचता है इसकी आवंटित स्मृति स्थान। लेकिन मुझे नहीं लगता कि मैं यह कैसे कर सकता हूं। मैं देखता हूं कि मैं एक एसटीएल कंटेनर के टेम्पलेट पैरामीटर में आवंटक प्रकार कैसे पारित कर सकता हूं, लेकिन मुझे एसटीएल कंटेनर के कन्स्ट्रक्टर में आवंटक आवृत्ति को पारित करने के समान कुछ चाहिए। एसटीएल में ऐसा करने का कोई तरीका है?एसटीएल कस्टम आवंटकों को विभिन्न मेमोरी रिक्त स्थान प्रबंधित करने के लिए

उत्तर

17

दुर्भाग्यवश एसटीएल आवंटकों के पास राज्य नहीं हो सकता है (या कम से कम सावधानी बरतनी है कि उस राज्य का उपयोग कैसे किया जाता है) - एक विशेष आवंटक प्रकार का प्रत्येक उदाहरण एसटीएल कंटेनर के लिए उनके साथ प्रभावी ढंग से काम करने के बराबर होना चाहिए। मुझे अभी विवरण याद नहीं है, लेकिन मुझे पता है कि स्कॉट मेयर्स "Effective STL" में इस समस्या पर चर्चा करते हैं, आइटम 10: आवंटन सम्मेलनों और प्रतिबंधों से अवगत रहें।

हालांकि, अगर आप allocators कि संभाजक प्रकार में समझाया और विभिन्न संभाजक टेम्पलेट के 'instantiations' का उपयोग किया जा रहा allocators के बीच मतभेद के साथ बहुत समान हैं टेम्प्लेट की गई है सकते हैं (प्रत्येक टेम्पलेट 'इन्स्टेन्शियशन' है एक अलग प्रकार) । दोबारा, मेरी यादें यह है कि मेयर्स इस स्पष्ट रूप से चर्चा करता है।

उदाहरण के लिए एक लेख से इस पैरा Anthony Aue, "Improving Performance with Custom Pool Allocators for STL" द्वारा देखें:

एक संभावित अधिक गंभीर चेतावनी है कि, के बाद से संभाजक nonstatic डेटा का उपयोग करता है, यह तकनीकी रूप से मानक के अनुरूप नहीं है क्योंकि मानक की आवश्यकता है कि एक ही की allocators प्रकार बराबर हो। इस मुद्दे की पूरी तरह से व्याख्या के लिए प्रभावी एसटीएल (आइटम 10) देखें। यह आवश्यक है कि किसी दिए गए प्रकार के लिए आवंटक उस प्रकार के आवंटक के किसी भी अन्य उदाहरण द्वारा आवंटित स्मृति को रद्द करने में सक्षम हो। मानक कंटेनरों के कई प्रयोगों के लिए, यह आवश्यकता अनावश्यक है (कुछ ड्रैकोनियन कह सकते हैं)। हालांकि, ऐसे दो मामले हैं जहां यह आवश्यकता बिल्कुल जरूरी है: सूची :: विभाजन और स्वैप()। स्वैप() का मामला विशेष रूप से गंभीर है क्योंकि अपवाद-सुरक्षित तरीके से कंटेनरों पर कुछ संचालन को लागू करने के लिए इसकी आवश्यकता होती है (अपवाद सी ++, आइटम 12 देखें)। तकनीकी रूप से, स्वैप हो सकता है (और कुछ मामलों में, उन आवंटकों के चेहरे में लागू किया जाता है जो समान वस्तुओं की तुलना नहीं करते हैं या प्रतिलिपि बनाई जा सकती है - डेटा के साथ आवंटकों को बदल दिया जा सकता है - लेकिन यह हमेशा ऐसा नहीं होता है। इस कारण से, यदि आप स्वैप() या सूची :: स्प्लिस का उपयोग कर रहे हैं, तो आपको होल्डिंग पॉलिसी सिंगलेटन का उपयोग करना सुनिश्चित करना चाहिए; अन्यथा, आप कुछ वास्तव में बुरा व्यवहार में भागने के लिए बाध्य हैं।

स्टीफन टी। Lavavej की चर्चा this newsgroup thread में भी देखें।

मैं बाद में अपडेट करूंगा अगर कोई और इस दौरान विवरण नहीं देता है।

+2

हालांकि, यह ध्यान देने योग्य है कि सी ++ 0x को असमान आवंटकों के लिए समर्थन की आवश्यकता होगी। –

+1

आप सही हैं कि ध्यान देने योग्य है - सी ++ 0x "स्कोप्ड ऑलोकेटर्स" पर स्ट्राउस्टअप का अक्सर पूछे जाने वाले प्रश्न: http://www.research.att.com/~bs/C++0xFAQ.html#scoped-allocator –

+0

+1 - इच्छा है कि मैं इस जवाब को और अधिक टक्कर दे सकता हूं। एसटीएल में आवंटक काफी नोब-विरोधी हैं - कार्यक्षमता योगदान देने से अधिक गूढ़ बग आकर्षित करते हैं। – Fox

0

शायद आप आवंटक प्रकारों का एक सेट कोड कर सकते हैं जिसमें अलग-अलग स्मृति रिक्त स्थानों के लिए एक स्थिर बिंदु शामिल है।

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

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

6

एसटीएल कंटेनर आपको कन्स्ट्रक्टर को तर्क के रूप में आवंटक को पास करने की अनुमति देते हैं।

उदाहरण के लिए यहाँ वेक्टर के लिए उपयुक्त निर्माता ये हैं:

explicit vector(const Allocator& = Allocator()); 
explicit vector(size_type n, const T& value = T(), 
    const Allocator& = Allocator()); 
template <class InputIterator> 
vector(InputIterator first, InputIterator last, 
    const Allocator& = Allocator()); 

डिफ़ॉल्ट रूप से, वे सिर्फ एक डिफ़ॉल्ट का निर्माण संभाजक का उपयोग करें।

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