2008-11-19 21 views
6

मुझे पता है कि new [] का उपयोग करने के बाद मुझे delete [] का उपयोग करना चाहिए, इसलिए auto_ptrnew [] का उपयोग करना इतना उज्ज्वल विचार नहीं है।विज़ुअल सी ++ में इसे हटाएं और हटाएं?

हालांकि, जबकि delete [] डिबगिंग (विजुअल स्टूडियो 2005 का उपयोग), मैंने देखा है कि कॉल एक समारोह है कि इस तरह देखा में चला गया:

void operator delete[](void * p) 
{ 
    RTCCALLBACK(_RTC_Free_hook, (p, 0)) 
    operator delete(p); 
} 

करता है इसका मतलब, [] वाक्य रचना विज़ुअल सी पर खो दिया है ++? यदि हां, तो क्यों? क्या यह सही वाक्यविन्यास को याद रखने के बोझ से डेवलपर से छुटकारा पाने के लिए है?

+0

'हटाएं [] पी' ऑपरेटर हटाएं [] (पी)' के बराबर नहीं है। –

उत्तर

26

इस कोड पर विचार करें:

class DeleteMe 
{ 
public: 
    ~DeleteMe() 
    { 
    std::cout << "Thanks mate, I'm gone!\n"; 
    } 
}; 

int main() 
{ 
    DeleteMe *arr = new DeleteMe[5]; 
    delete arr; 
    return 0; 
} 

आप चलाते हैं कि VS2005 में इसे प्रिंट होगा:

Thanks mate, I'm gone!

आप main() बदलते हैं तो सही ढंग से सी ++ मानक का पालन करने के लिए:

int main() 
{ 
    DeleteMe *arr = new DeleteMe[5]; 
    delete[] arr; 
    return 0; 
} 

यह प्रिंट करेगा:

Thanks mate, I'm gone! 
Thanks mate, I'm gone! 
Thanks mate, I'm gone! 
Thanks mate, I'm gone! 
Thanks mate, I'm gone!

पैर में खुद को गोली मारो मत। VS2005 नहीं सही चीज़ करें यदि आप नए/हटाए गए विभिन्न स्वादों को मेल नहीं खाते हैं। न तो कोई अन्य सी ++ मानक अनुरूप अनुरूप कंपाइलर होगा।

कुछ संकलक जादू operator new और operator delete (और उनके विभिन्न स्वादों) के आसपास चल रहा है, मूल रूप से ctors और dtors करने के लिए कॉल पर्दे के पीछे जोड़ रहे हैं नहीं है। यह जादू उन छोटे ब्रैकेट [] पर निर्भर करता है, इसलिए उन्हें खोना न करें या आप जादू खो देंगे।

+0

ठीक है, मैं स्वीकार करता हूं कि यह जादू के माध्यम से किया जाता है। :) –

2

सिर्फ इसलिए कि वे अब भी काम कर सकते हैं, इसका मतलब यह नहीं है कि आप जरूरी रूप से उनका इलाज कर सकते हैं - व्यवहार बदल सकता है। और इसके अलावा, कौन परवाह करता है - आपको अपना कोड लिखना चाहिए ताकि आपको याद रखना पड़े।

इसके अतिरिक्त, आप सरणी हटाने के लिए scoped_array का उपयोग कर सकते हैं।

+0

मुझे पता है, हमें चाहिए, लेकिन अब तक हम बूस्ट का उपयोग नहीं करते हैं।:( –

+0

मेरा मानना ​​है कि scoped_array (और अन्य बूस्ट स्मार्ट पॉइंटर प्रकार) TR1 का हिस्सा हैं। आपके पास बूस्ट के बिना पहले से ही हो सकता है। – Ferruccio

+0

मुझे वीएस2005 के बारे में हिस्सा याद आया। मुझे लगता है कि टीआर 1 वीएस -2008 एसपी 1 में है। – Ferruccio

4

मुझे लगता है कि यह सिर्फ एक कार्यान्वयन विस्तार है। उनके ढेर आवंटक एरे और पॉइंटर्स को मुक्त करते समय उसी तरह काम करते हैं।

लेकिन चूंकि मानक दो मामलों के लिए कार्यान्वयन के लिए अलग-अलग एल्गोरिदम की अनुमति देता है, इसलिए आपको वास्तव में यह मानना ​​नहीं चाहिए कि delete और delete[] वही काम करें। व्यवहार कंपाइलर संस्करणों के बीच भी बदल सकता है।

2

शायद आपके द्वारा हटाए गए डेटा में विनाशक नहीं थे? यदि ऐसा है, तो यह सरल हटाने समझ में आ जाएगा। यह शून्य के बाद * काम कर रहा है।

वैसे भी, आपको यह सुनिश्चित करने के लिए हटाएं [] का उपयोग करना होगा कि विनाशक सरणी में प्रत्येक तत्व के लिए चलाया जाता है।

2

बिना किसी सरणी को हटाने [] केवल स्मृति को मुक्त करेगा, लेकिन सरणी में प्रत्येक ऑब्जेक्ट में विनाशकों को कॉल नहीं करेगा। तो, तकनीकी रूप से आपको केवल [] की आवश्यकता है यदि आपके विनाशक को बुलाया जाना चाहिए।

+0

मैं निश्चित रूप से आपकी पहली बार संशोधित करूंगा बयान क्योंकि यह सही और खतरनाक नहीं है, भले ही आप अंत में सही स्पष्टीकरण दें। –

+0

आप सही हैं, वीएस 2005 वास्तव में परवाह करते हैं। और वे रन टाइम के दौरान भी समस्या का पता लगाते हैं। मैंने इसे बहुत समय पहले परीक्षण किया था, इसलिए मैं अनुमान है कि एमएस ने इसे बदल दिया है। –

+0

यदि आप '[]' को छोड़ देते हैं, तो आप नाक राक्षसों को बुलाते हैं। –

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