2008-12-12 14 views
12

मैंने अभी सी ++ निर्माण के बारे में सीखा है जिसे "प्लेसमेंट न्यू" कहा जाता है। यह आपको वास्तव में नियंत्रित करने की अनुमति देता है जहां एक सूचक सूचक में इंगित करता है। यह इस तरह दिखता है:सी ++ निर्माण "प्लेसमेंट नया" के उपयोग क्या हैं?

#include <new>  // Must #include this to use "placement new" 
#include "Fred.h"  // Declaration of class Fred 

void someCode() 
{ 
    char memory[sizeof(Fred)]; 
    void* place = memory; 

    Fred* f = new(place) Fred(); // Create a pointer to a Fred(), 
            // stored at "place" 

    // The pointers f and place will be equal 

    ... 
} 

(उदाहरण C++ FAQ Lite से)

इस उदाहरण में, फ्रेड की this सूचक place के बराबर हो जाएगा।


मैंने इसे एक बार या दो बार हमारी टीम के कोड में उपयोग किया है। आपके अनुभव में, यह निर्माण क्या सक्षम बनाता है? क्या अन्य पॉइंटर भाषाओं में समान संरचनाएं होती हैं? मेरे लिए, यह फोरट्रान में equivalence की याद दिलाता है, जो स्मृति में समान स्थान पर कब्जा करने के लिए अलग-अलग चर की अनुमति देता है।

उत्तर

4

मैं कर्नेल मोड में C++ करते समय इस निर्माण का उपयोग करता हूं।

मैं कर्नेल मोड मेमोरी आवंटक का उपयोग करता हूं और आवंटित खंड पर ऑब्जेक्ट का निर्माण करता हूं।

यह सब कक्षाओं और कार्यों में लपेटा गया है, लेकिन अंत में मैं एक प्लेसमेंट नया करता हूं।

1

हार्ड ड्राइव पर फ़ाइल में स्मृति को पिंग करते समय यह उपयोगी हो सकता है, जो बड़ी वस्तुओं में हेरफेर करते समय कोई भी कर सकता है।

+0

आप उस पर विस्तृत कर सकते हैं? पेजिंग के लिए उपयोगी? या वापस पेजिंग के लिए उपयोगी है? मैं पेजिंग को वापस देखता हूं, पेजिंग आउट की कल्पना नहीं करता हूं। – ApplePieIsGood

5

प्लेसमेंट नए का उपयोग प्रकार-सुरक्षित यूनियनों, जैसे बूस्ट के variant बनाने के लिए किया जा सकता है।

यूनियन क्लास में बफर होता है जो कि इसमें शामिल होने वाले सबसे बड़े प्रकार के रूप में बड़ा होता है (और पर्याप्त संरेखण के साथ)। यह आवश्यकतानुसार बफर में new एस ऑब्जेक्ट्स रखता है।

12

यह भी एम्बेडेड प्रोग्रामिंग के लिए प्रयोग किया जाता है, जहां आईओ उपकरणों अक्सर विशिष्ट स्मृति पर मैप किए जाते संबोधित करते

14

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

इस तरह की चीज सी में भी की गई थी, लेकिन चूंकि सी में कोई रचनाकार नहीं है, इसलिए उसे किसी भी भाषा समर्थन की आवश्यकता नहीं थी।

+1

जिस समस्या का आप वर्णन कर रहे हैं उसे उचित मेमोरी आवंटक का उपयोग करके हल किया जाना चाहिए, प्लेसमेंट को अधिभारित करना संभवतः कार्रवाई का सबसे अच्छा तरीका नहीं हो सकता है। –

+0

सही - टेम्पलेट लाइब्रेरी का उपयोग करते समय। अन्यथा, प्लेसमेंट नया है। – jmucchiello

+0

निश्चित रूप से, सी ++ में बहुत से स्थान हैं जहां अब ऐसा करने का एक बेहतर तरीका है। उदाहरण के लिए, मैंने वर्षों में हटाया नहीं है []। हालांकि, वहां बहुत सारे पुराने कोड हैं जो प्लेसमेंट का उपयोग करते हैं और ऐसे में। –

0

ढेर पर एक वस्तु का आवंटन करने का एक तरीका की तरह मुझे लगता है ..

+0

वैसे, वैनिला नया क्या करता है, लेकिन आमतौर पर आपको स्टैक पर निर्दिष्ट करने के लिए यह नहीं मिलता है। –

+0

टॉमी: आप ढेर –

+0

के बारे में सोच रहे हैं, ऊपर दिए गए मूल पोस्ट किए गए प्रश्न में, वास्तव में यह स्टैक पर नया हो रहा है, क्योंकि सरणी बफर बनाया गया है। लेकिन यह मामला नहीं होना चाहिए। शायद एक बेहतर उदाहरण ने मैलोक() के साथ हीप आवंटित मेमोरी का उपयोग किया होगा ... – ApplePieIsGood

7

मैं इसे का उपयोग किया है जब एक साझा स्मृति खंड में वस्तुओं का निर्माण।

7

ऑब्जेक्ट्स जैसे अपने कंटेनर का निर्माण करते समय इसका उपयोगी।

उदाहरण के लिए यदि आप एक वेक्टर बनाना चाहते हैं। आप वस्तुओं की एक बड़ी संख्या के लिए स्थान आरक्षित है कि आपने कभी विधि उस वस्तु की निर्माता आह्वान नहीं करता है के साथ स्मृति आवंटित करना चाहते (नए चार तरह [sizeof (वस्तु) * reserveSize])। फिर जब लोग वेक्टर में ऑब्जेक्ट्स जोड़ना शुरू करते हैं तो आप उन्हें आवंटित स्मृति में कॉपी करने के लिए प्लेसमेंट का उपयोग करते हैं।

template<typename T> 
class SillyVectorExample 
{ 
    public: 
     SillyVectorExample() 
      :reserved(10) 
      ,size(0) 
      ,data(new char[sizeof(T) * reserved]) 
     {} 
     void push_back(T const& object) 
     { 
      if (size >= reserved) 
      { 
       // Do Somthing. 
      } 
      // Place a copy of the object into the data store. 
      new (data+(sizeof(T)*size)) T(object); 
      ++size; 
     } 
     // Add other methods to make sure data is copied and dealllocated correctly. 
    private: 
     size_t reserved; 
     size_t size; 
     char* data; 
}; 

पीएस। मैं ऐसा करने की वकालत नहीं कर रहा हूं। कंटेनर कैसे काम कर सकते हैं यह एक सरलीकृत उदाहरण है।

+0

क्या आपके पास वास्तव में इसका उपयोग करने के बारे में कोई और ठोस उदाहरण हैं? –

+0

आपका मतलब अधिक ठोस क्या है? कंटेनर एक अच्छा उदाहरण हैं। मुझे यकीन है कि एसटीएल कंटेनर जिन्हें अंतरिक्ष आरक्षित करने की आवश्यकता है, कुछ रूपों में प्लेसमेंट नए का उपयोग करेंगे (शायद ऑलोकेटर के माध्यम से, लेकिन मैंने नहीं देखा है, इसलिए यह सिर्फ एक धारणा है)। –

1

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

4

प्लेसमेंट नया संकेत बराबर बनाने के बारे में नहीं है (आप बस उस के लिए काम का उपयोग कर सकते!)।

प्लेसमेंट नया किसी ऑब्जेक्ट को किसी विशेष स्थान पर बनाने के लिए है। सी ++ में ऑब्जेक्ट बनाने के तीन तरीके हैं, और प्लेसमेंट नया एकमात्र ऐसा है जो आपको उस वस्तु पर "स्पष्ट" कहां पर स्पष्ट नियंत्रण देता है। यह साझा स्मृति, निम्न-स्तरीय डिवाइस I/O, और मेमोरी पूल/आवंटन कार्यान्वयन सहित कई चीजों के लिए उपयोगी है।

ढेर आवंटन के साथ, वस्तु ढेर के शीर्ष पर, जहाँ भी है कि वर्तमान में होने वाला पर निर्माण किया है।

साथ

"नियमित" नई, वस्तु ढेर पर एक प्रभावी रूप से मनमाने ढंग से किए गए पते पर निर्माण के रूप में मानक पुस्तकालय द्वारा प्रबंधित (जब तक आप ऑपरेटर नई अधिरोहित है) है।

प्लेसमेंट नया कहता है "मुझे इस पते पर विशेष रूप से एक वस्तु बनाएं", और इसका कार्यान्वयन केवल ऑपरेटर का एक अधिभार है जो पॉइंटर को पास करता है, जो कि नई मशीनरी की शेष राशि को प्राप्त करने के साधन के रूप में देता है ऑपरेटर, जो ऑपरेटर के नए फ़ंक्शन द्वारा लौटाई गई स्मृति में ऑब्जेक्ट बनाता है।

यह भी ध्यान देने योग्य बात है कि ऑपरेटर नए कार्य को मनमाने ढंग से तर्क (किसी अन्य समारोह के रूप में) के साथ अतिभारित किया जा सकता लायक है। ये अन्य तर्क "नए (तर्क 2, arg3, ..., argN)" वाक्यविन्यास के माध्यम से पारित किए जाते हैं। Arg1 हमेशा "आकार (जो भी आप बना रहे हैं) के रूप में पारित किया जाता है"।

0

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

2

सटीक प्लेसमेंट को नियंत्रित करके, आप स्मृति में चीजों को संरेखित कर सकते हैं और यह कभी-कभी CPU fetch/कैश प्रदर्शन को बेहतर बनाने के लिए उपयोग किया जा सकता है। कभी वास्तव में, प्रयोग में देखा था, हालांकि

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