2009-01-23 14 views
15

क्या हैप (malloc) के बजाय स्टैक (एला alloca) पर आवंटित करने के लिए new कीवर्ड का उपयोग करने का कोई तरीका है?ढेर के बजाय स्टैक पर नया (जैसे एलोका बनाम मॉलोक)

मुझे पता है कि मैं अपना खुद का हैक कर सकता हूं लेकिन मैं नहीं चाहूंगा।

उत्तर

23

ढेर पर आवंटित करने के लिए, या तो मूल्य द्वारा एक स्थानीय चर के रूप में अपने वस्तु का ऐलान करते हैं या आप वास्तव में एक सूचक प्राप्त करने के लिए alloca उपयोग कर सकते हैं और फिर इन-जगह नए ऑपरेटर का उपयोग करें:

void *p = alloca(sizeof(Whatever)); 
new (p) Whatever(constructorArguments); 

हालांकि, एलोका और इन-प्लेस का उपयोग करते समय नया यह सुनिश्चित करता है कि स्मृति वापसी पर मुक्त हो जाती है, तो आप स्वचालित विनाशक कॉलिंग छोड़ देते हैं। यदि आप यह सुनिश्चित करने की कोशिश कर रहे हैं कि स्मृति को दायरे से बाहर निकलने पर मुक्त किया गया है, तो std::auto_ptr<T> या कुछ अन्य स्मार्ट सूचक प्रकार का उपयोग करने पर विचार करें।

12

जेफरी हंटिन काफी सही है कि आप इसे आवंटन के साथ स्टैक पर बनाने के लिए प्लेसमेंट नया उपयोग कर सकते हैं। लेकिन, गंभीरता से, क्यों ?! इसके बजाए, बस करें:

class C { /* ... */ }; 

void func() { 
    C var; 
    C *ptr = &var; 

    // do whatever with ptr 
} 

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

+2

आपका उदाहरण बिल्कुल वैल्यू द्वारा स्थानीय चर के रूप में घोषित करने का मतलब है। –

+0

नोट: क्लास में सीपीपी में परिभाषित एक खाली कन्स्ट्रक्टर होना चाहिए, यदि आपके पास पहले से ही एक गैर-खाली कन्स्ट्रक्टर परिभाषित है। – kevinf

+0

मुझे जो मामला मिला है - कहें कि 'सी' में उप-वर्ग 'सी 1' और 'सी 2' में ओवरराइड' वर्चुअल 'विधि है। तो मैं 'सी * पीआरटी = मानदंड करना चाहूंगा? नया (एलोका (आकार (सी 1))) सी 1 (...): नया (एलोका (आकार (सी 2))) सी 2 (...); ' – rampion

5

आप कर सकता है:

Whatever* aWhatever = new (alloca(sizeof(Whatever))) Whatever; 

आप कर सकते थे विनाश मुझे लगता है करने के लिए एक आरए II वर्ग का उपयोग करता है (संपादित करें: इसके अलावा this other answer for more information on potential problems with this approach देखें):

template <class TYPE> 
class RAII 
    { 
    public: 
     explicit RAII(TYPE* p) : ptr(p) {} 
     ~RAII() { ptr->~TYPE(); } 
     TYPE& operator*() const { return *ptr; } 
    private: 
     TYPE* ptr; 
    } 

void example() 
    { 
    RAII<Whatever> ptr = new (alloca(sizeof(Whatever))) Whatever; 
    } 

आप को छिपाने के लिए एक मैक्रो इस्तेमाल कर सकते हैं alloca।

सादर DaveF

2

जब जीसीसी साथ _alloca() का उपयोग कर

जीसीसी सी में एक bug which makes _alloca() incompatible with SJLJ exception handling है ++ (Dwarf2 सही ढंग से काम करने के लिए रिपोर्ट किया गया है) सावधान रहें। जब मेमोरी आवंटित फ़ंक्शन से एक अपवाद फेंक दिया जाता है, तो बग विनाशकों को चलाने से पहले भ्रष्टाचार का कारण बनता है। इसका मतलब यह है कि आवंटित ऑब्जेक्ट पर काम करने वाली किसी भी आरएआईआई कक्षा को को ठीक से काम करने के लिए किसी अन्य फ़ंक्शन में चलाया जाना चाहिए। ऐसा करने का उचित तरीका इस तरह दिखता है:

void AllocateAndDoSomething() 
{ 
    Foo* pFoo = reinterpret_cast<Foo*>(_alloca(sizeof(Foo))); 
    new (pFoo) Foo; 

    // WARNING: This will not work correctly! 
    // ScopedDestructor autoDestroy(pFoo); 
    // pFoo->DoSomething(); 

    // Instead, do like this: 
    DoSomething(pFoo); 
} 

void DoSomething(Foo* pFoo) 
{ 
    // Here, destruction will take place in a different call frame, where problems 
    // with _alloca() automatic management do not occur. 
    ScopedDestructor autoDestroy(pFoo); 
    pFoo->DoSomething(); 
} 
संबंधित मुद्दे