2010-04-17 9 views
8

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

उत्तर

10

सबसे पहले, यह ध्यान रखना महत्वपूर्ण है कि new और delete या तो विश्व स्तर पर या केवल एक वर्ग के लिए अधिभारित किया जा सकता है। दोनों मामलों को this article में दिखाया गया है। यह भी ध्यान रखना महत्वपूर्ण है कि यदि आप new ओवरलोड करते हैं तो आप लगभग delete को अधिभारित करना भी चाहते हैं।

operator new और operator delete के बारे में कुछ महत्वपूर्ण नोट्स हैं:

  1. सी ++ मानक की आवश्यकता है एक वैध सूचक दिया जाता है कि भले ही आकार इसे करने के लिए पारित कर दिया 0.
  2. वहाँ भी operator new[] और operator delete[] है, तो उनको अधिभारित करने के बारे में मत भूलना।
  3. व्युत्पन्न कक्षाएं operator new और उसके भाइयों का उत्तराधिकारी है, इसलिए उनको ओवरराइड करना सुनिश्चित करें।

प्रभावी सी ++, आइटम 8 में, स्कॉट Meyers कुछ pseudocodish उदाहरण में शामिल हैं:

void * operator new(size_t size)  // your operator new might 
{          // take additional params 
    if (size == 0) {      // handle 0-byte requests 
    size = 1;       // by treating them as 
    }          // 1-byte requests 
    while (1) { 
    attempt to allocate size bytes; 
    if (the allocation was successful) 
     return (a pointer to the memory); 

    // allocation was unsuccessful; find out what the 
    // current error-handling function is (see Item 7) 
    new_handler globalHandler = set_new_handler(0); 
    set_new_handler(globalHandler); 

    if (globalHandler) (*globalHandler)(); 
    else throw std::bad_alloc(); 
    } 
} 


void operator delete(void *rawMemory) 
{ 
    if (rawMemory == 0) return; // do nothing if the null 
           // pointer is being deleted 
    deallocate the memory pointed to by rawMemory; 
    return; 
} 

अधिक जानकारी के लिए, मैं निश्चित रूप से अप प्रभावी सी ++ चुनते थे।

+0

तो, क्या मैं इसे एक हेडर और संदर्भ में रखूंगा जो कि मेरी सभी फाइलों में हेडर है? – Steve

+0

ठीक है, आप परिभाषाओं को एक स्रोत फ़ाइल में डाल देंगे, लेकिन हाँ। – rlbond

+0

बस एक छोटा फुटनोट: आप एक 'ऑपरेटर नया (आकार_टी गिनती, आकार_टी संरेखण)' भी परिभाषित कर सकते हैं ताकि आप स्पष्ट रूप से संरेखण को नए ऑपरेटर के लिए तर्क के रूप में पास कर सकें। इसे 'नया (संरेखण) संरेखित टाइप' – user666412

2

new को pointer [...] suitably aligned so that it can be converted to a pointer of any complete object type (मानक के §3.7.3.1) को वापस करने की आवश्यकता है।

एफडब्ल्यूआईडब्ल्यू, सी ++ 0x alignof जोड़ देगा जो आपको किसी विशेष प्रकार के लिए आवश्यक संरेखण बताएगा।

+3

दुर्भाग्यवश, किसी कारण से मैंने वास्तव में कभी नहीं समझा है, संकलक आमतौर पर 128-बिट सिम प्रकार के लिए इस नियम को लागू नहीं करते हैं। मेरा मानना ​​है कि वे आम तौर पर 8-बाइट संरेखण के साथ 'नया' हैं। – jalf

+0

@jalf: दो कारण: (1) अधिक गठबंधन आवंटन, ब्लॉक प्रति आवंटन ओवरहेड जितना अधिक होगा। यदि आप 17-बाइट आवंटन करते हैं, तो आप उन्हें 16-संरेखित करने और केवल 4-संरेखित करने के बीच एक अंतर देखेंगे। (2) (जीएनयू-विशिष्ट), ग्लिबैक जीसीसी की तुलना में कम मंच-विशिष्ट मान्यताओं को बनाता है, और वास्तव में यह नहीं जानता कि सबसे बड़ा प्रकार यह है कि किसी सिस्टम पर कुछ कंपाइलर का समर्थन हो सकता है। लेकिन जीसीसी "मॉलोक को सीधे ग्लिबैक पास करने के लिए" चाहता है, अपने स्वयं के संरेखण तंत्र को नहीं जोड़ता है, मॉलोक की तुलना में और भी अधिक ओवरहेड के साथ। मैंने कहीं इसके बारे में एक दिलचस्प सार्वजनिक तर्क पढ़ा। –

+0

...आखिरकार, कंपाइलर सिद्धांत में 15 बाइट्स पर सभी आवंटन पर ओवरहेड से परहेज करते हुए कॉल को 'नई सिमड_Type' पर संरेखित करना चुन सकता है। लेकिन यह अभी भी गलत होगा, क्योंकि यदि आप ऐसा करने जा रहे हैं तो आपको कॉल को 'नए char [sizeof (SIMD_Type)]' पर भी संरेखित करना चाहिए। सर्वसम्मति यह है कि सिम प्रकार के प्रकार "उचित निर्मित प्रकार" नहीं हैं, वे विशेष चीजें हैं जिन्हें विशेष रूप से आवंटित किया जाना चाहिए। –

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