2009-11-17 2 views
7

मैं करता हूँ, कहते हैं किसी ++ सरणी को नष्ट ऑपरेटर वाक्य रचना

Foo* array = new Foo[N];

मैं हमेशा इसे इस तरह

delete[] array;

हालांकि हटा देने के बाद, कभी कभी मैं इसे इस तरह से देखा है के बाद:

delete[N] array;

जैसा कि यह संकलित और काम करता है (कम से कम msvc2005 में), मुझे आश्चर्य है: ऐसा करने का सही तरीका क्या है? फिर यह दूसरी तरफ संकलित क्यों करता है?

उत्तर

13

आप इस एमएसडीएन लिंक को देख सकते हैं: delete[N] operator। मूल्य अनदेखा किया जाता है।

संपादित मैं VC9 पर इस नमूना कोड की कोशिश की:

int test() 
{ 
    std::cout<<"Test!!\n"; 
    return 10; 
} 

int main() 
{ 
    int* p = new int[10]; 
    delete[test()] p; 
    return 0; 
}; 

आउटपुट है: टेस्ट !!

तो अभिव्यक्ति का मूल्यांकन किया जाता है लेकिन वापसी मूल्य को नजरअंदाज कर दिया जाता है। मैं कम से कम कहने में हैरान हूं, मैं एक परिदृश्य के बारे में नहीं सोच सकता कि इसकी आवश्यकता क्यों है।

+0

+1। उपयोगी जानकारी –

+0

क्या इसका मतलब है कि आप [2 एन] सरणी हटा सकते हैं; और यह –

+0

संकलित करेगा धन्यवाद, यह वही है जो मैं ढूंढ रहा था। – raven

4

सही तरीका delete[] array; करना है। मुझे यह भी पता नहीं था कि delete[N] array; संकलित होगा (और मुझे शक है कि यह चाहिए)।

+1

यह एक चेतावनी सी 4208 के साथ वीसी 9 पर संकलित करता है: गैर-मानक विस्तार का उपयोग किया गया: हटाएं [एक्सपी] - एक्सप मूल्यांकन किया गया लेकिन अनदेखा किया गया 'मेरा मतलब यह नहीं है कि – Naveen

+1

का मतलब है कि कोड (1) मान्य सी ++ नहीं है, और (2) अभिव्यक्ति 'एन' का मूल्यांकन किया जाता है लेकिन अनदेखा किया जाता है। यह काफी अप्रासंगिक है, लेकिन यह बताता है कि क्या होता है यदि आपने 'हटाएं [एन ++] सरणी लिखा है; '- एन पहले वृद्धि हुई है, और फिर अनदेखा किया गया है। – MSalters

+0

वास्तव में, इसे पहली बार अनदेखा किया जाता है और फिर बढ़ाया जाता है :) – raven

5

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

विजुअल स्टूडियो कई चीजों को संकलित करता है जो इसे नहीं करना चाहिए।

+4

"विजुअल स्टूडियो कई चीजों को संकलित करता है जो इसे नहीं करना चाहिए।" तथास्तु। – sbi

10

delete [N] array अमान्य है। इसे सी ++ मानक में परिभाषित नहीं किया गया है: सेक्शन 5.3.5 एक हटाए गए अभिव्यक्ति को delete expr या delete [] expr के रूप में परिभाषित करता है, और कुछ भी नहीं। यह जीसीसी (संस्करण 4.1.2) पर संकलित नहीं है। विज़ुअल सी ++ में क्यों संकलित होता है: माइक्रोसॉफ्ट से पूछें।

+0

कौन सी सी ++ मानक? और, क्या आपके पास एक लिंक/रेफरी है, जहां कोई इसे पा सकता है? – Kissaki

+1

@ किसाकी: मैं सी ++ 03 का जिक्र कर रहा होता, जो कानूनी रूप से ऑनलाइन उपलब्ध नहीं है। हालांकि, शब्द सी ++ 11 में बहुत समान है, जिसका एक मसौदा http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf –

+0

Ah पर उपलब्ध है, धन्यवाद .. – Kissaki

-2

यदि यह काम करता है, तो यह एक गैर-मानक विस्तार है।

delete [] array; 

सही फॉर्म है।

delete array; 

कभी-कभी काम भी करेगा लेकिन कार्यान्वयन निर्भर (इस प्रकार गलत) है।

+1

दूसरे रूप का व्यवहार (ब्रैकेट के बिना) गैर-सरणी पॉइंटर्स के लिए स्पष्ट रूप से परिभाषित किया गया है। सरणी के लिए इसका व्यवहार नहीं है। वैसे भी, मुझे लगता है कि यही कारण है कि किसी ने आपको वोट दिया। –

+1

'सरणी हटाएं' शब्द के किसी भी अर्थ में "काम" नहीं करता है, जब तक कि आपका मतलब यह न हो कि यह प्रोग्राम को क्रैश नहीं करता है। यह पहली जगह आवंटित सभी स्मृति को पुनः प्राप्त नहीं करेगा, और यदि यह क्रैश नहीं होता है तो यह केवल सरणी में पहली वस्तु पर विनाशक चलाएगा। (यदि आपने 'नया Foo [0] 'किया है तो भी एक त्रुटि है।) – Bill

+1

@ बिल: मेरी इच्छा है कि मैं टिप्पणी को कम-वोट कर सकता हूं। आपका कथन कभी-कभी सच हो सकता है और दूसरी बार यह संभवतः नहीं हो सकता है। यहां देखें: http://stackoverflow.com/questions/1553382/1553407#1553407 और मेरी टिप्पणी यहां: http://stackoverflow.com/questions/1553382/1553391#1553391 – sbi

4

पहला बिंदु: नए के सरणी रूप का उपयोग करने के लिए लगभग कोई अच्छा कारण नहीं है या इसके साथ शुरू करने के लिए हटाएं - std :: vector (या कुछ अन्य कंटेनर) का उपयोग करें।

दूसरा: सी ++ की अंधेरे उम्र में, आपको उस सरणी का आकार निर्दिष्ट करना था जिसे आप हटा रहे थे, इसलिए यदि आपने x = new T[N] का उपयोग किया था, तो मिलान हटाना delete [N] x था। आकार को स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता लंबे पहले हटा दी गई थी, लेकिन कुछ कंपाइलर्स (विशेष रूप से जो प्राचीन कोड के साथ पिछड़े संगतता की परवाह करते हैं) अभी भी इसे अनुमति देते हैं।

जब तक आपको वास्तव में एक प्राचीन कंपाइलर (20 वर्ष या उससे अधिक) के साथ संगत रहने की आवश्यकता नहीं है, तो आपको इसका उपयोग नहीं करना चाहिए। फिर फिर, जब तक कि आपको इतने पुराने कंपाइलर के साथ संगत रहने की आवश्यकता न हो, यह किसी भी मानक कंटेनर का समर्थन नहीं करता है, तो आपको पहले के सरणी रूप का उपयोग नहीं करना चाहिए या पहले स्थान पर हटाना नहीं चाहिए। अभी रोको!

+0

इतिहास सबक के लिए धन्यवाद। फिर, अगर मुझे किसी तीसरे पक्ष के पुस्तकालय में गतिशील सरणी पास करनी पड़े, तो मानक कंटेनर के साथ ऐसा करने का सही तरीका क्या होगा? – raven

+0

एक वेक्टर का प्रयोग करें। जब आपको पता/लंबाई पारित करने की आवश्यकता होती है, तो उपयोग करें और वीसी [0], और vec.size()। –

+0

+1: मानक के सीपी '94 ड्राफ्ट में सिंटैक्स पहले से ही 'हटाएं []' था। और उसी वर्ष, डिजाइन एंड इवोल्यूशन (पी 218) ने टिप्पणी की थी कि यह वाक्यविन्यास "... बहुत त्रुटि-प्रवण साबित हुआ, इसलिए तत्वों की संख्या को ट्रैक रखने का बोझ इसके बजाय कार्यान्वयन पर रखा गया था।" –

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

  • कोई संबंधित समस्या नहीं^_^