2012-01-19 8 views
6

एसटीडी कॉल :: वेक्टर :: वापस() दुर्घटना मेरा कार्यक्रम मुझे यकीन है कि क्या इस कोड के साथ गलत क्या है नहीं कर रहा हूँ करता है:क्यों

std::vector<int> myVector(0); 

if (myVector.back() == 12) 
    myVector.push_back(12); 

ऐसा लगता है कि() वापस बुला एक खाली वेक्टर पर दुर्घटनाओं कार्यक्रम।

मुझे समझ में नहीं आता कि यह क्यों दुर्घटनाग्रस्त हो रहा है? back() पर कॉल करने से पहले हमें वेक्टर की लंबाई की जांच करने की आवश्यकता है? या यह संभव है कि यह एक बग है?

प्रलेखन कहता है कि यदि वेक्टर खाली है तो यह एक अपरिभाषित मान लौटाता है।

+1

मुझे संदेह है कि यह आपको किसी व्यक्ति को सी ++ मानक के बजाय एमएसडीएन का उपयोग करने के लिए -1 देने के लिए है। कार्यान्वयनकर्ताओं को आगे परिभाषित करने की अनुमति है कि मानक कहां यूबी हैं, उनके मामले में उनके कार्यान्वयन क्या करते हैं, इसलिए अगर एमएस यह गारंटी देना चाहता है कि खाली वेक्टर पर इस्तेमाल होने पर 'बैक()' वापस आ जाएगा, तो वे ऐसा करने के हकदार हैं। यदि आप एमएसवीसी ++ का उपयोग कर रहे हैं तो आप उनके दस्तावेज़ों को पढ़ने के हकदार हैं। लेकिन यह 1 के बजाय यह हो सकता है कि किसी भी तरह से "अपरिभाषित मूल्य" का उपयोग करके, क्रैश हो सकता है। –

+0

@SteveJessop मुझे लगता है कि एमएसडीएन सी ++ मानक का कार्यान्वयन है। लेकिन यह अजीब लगता है कि वैध तत्व पर एक विधि को कॉल करना (जहां तक ​​मुझे खाली पता है वेक्टर एक वैध तत्व है) मेरे प्रोग्राम को दुर्घटनाग्रस्त करता है। वैसे यदि मानक ऐसा कहता है, तो हो सकता है :) – MBen

+1

एमएसवीसी ++ * एक * कार्यान्वयन (लगभग) सी ++ मानक है। अन्य कार्यान्वयन अलग-अलग व्यवहार करते हैं, यदि मानक व्यवहार को नहीं बताता है। एक खाली वेक्टर पर 'बैक()' को कॉल करने के लिए मानक परिभाषित करने का कारण यह नहीं है कि कार्यान्वयन के लिए विशेष-केस कोड की आवश्यकता नहीं है। इसलिए वे यह जांचने के लिए तेज़ होने का विकल्प चुन सकते हैं कि वेक्टर खाली था या नहीं, और अलग-अलग मामलों में अलग-अलग चीजें करते हैं। जब आप कुछ गलत करते हैं तो वे दुर्घटनाग्रस्त हो जाएंगे (या बदतर)। यह अजीब लग सकता है, लेकिन यह भाषा के डिजाइन के हिस्से के रूप में एक व्यापार बंद है। –

उत्तर

13

क्या हमें वापस कॉल करने से पहले वेक्टर की लंबाई की जांच करने की आवश्यकता है?

एक शब्द में: हाँ। यह तुम्हारी बग है, आपका वेक्टर खाली है इसलिए कोई "बैक" तत्व नहीं है।

प्रलेखन कहना चाहिए (यह कुछ भी कहते हैं) कि एक खाली वेक्टर पर back() बुला का कारण बनता है अपरिभाषित व्यवहार, नहीं है कि यह एक अपरिभाषित मान देता है।

+0

किसी कारण से, एमएसडीएन कहता है "वापसी मूल्य अपरिभाषित है" (http://msdn.microsoft.com/en-us/library/0532x4xk%28v=vs.80%29.aspx)। लेकिन यह भी कहता है, "_SECURE_SCL 1 के साथ संकलन करते समय, यदि आप खाली वेक्टर में किसी तत्व को एक्सेस करने का प्रयास करते हैं तो रनटाइम त्रुटि उत्पन्न होगी"। मुझे नहीं पता (ए) क्यों एमएस एक संदर्भ के रूप में संदर्भ का जिक्र कर रहा है, या (बी) वे किसी संदर्भ के विचार के साथ "अपरिभाषित मूल्य" की धारणा को कैसे वर्गीकृत करते हैं जिसके परिणामस्वरूप रनटाइम त्रुटि होती है । लेकिन वह रनटाइम त्रुटि वही हो सकती है जो प्रश्नकर्ता "क्रैशिंग" के रूप में वर्णित है। –

+0

मुझे अभी भी लगता है कि यह अजीब बात है कि वैध तत्व पर एक विधि को कॉल करना मेरे प्रोग्राम को दुर्घटनाग्रस्त करता है। – MBen

+0

@MBen: लेकिन आपके वेक्टर में कोई तत्व नहीं हैं; यह 'बैक()' की पूर्व शर्त है कि आपके वेक्टर में कम से कम एक तत्व है। इंटरफ़ेस को परिभाषित करने का यही तरीका है। आपको यह सुनिश्चित करने की आवश्यकता है कि आपका इनपुट 'back()' को कॉल करने का प्रयास करने से पहले पूर्व शर्त का अनुपालन करता है। –

5

C++ 11 मानक इस बताता है:

23.3.2.8/3

एक शून्य आकार सरणी के लिए सामने() या वापस() कॉल की ई एफएफ ect unde फाई नेड है।

चूंकि व्यवहार अपरिभाषित है, कुछ भी हो सकता है। आप दुर्घटनाग्रस्त होने के लिए भाग्यशाली थे।

+0

मुझे नहीं लगता कि मैं भाग्यशाली हूं, यह अजीब लगता है कि वैध पर एक विधि बुला रहा है मूल्य मेरे कार्यक्रम दुर्घटनाग्रस्त हो जाता है। – MBen

+3

@MBen यूबी पर प्रोग्राम क्रैश होने के कारण अच्छा है, क्योंकि त्रुटि को पकड़ना आसान है। जब कभी-कभी यह काम करता है और कभी-कभी नहीं, तो बग को ढूंढना बहुत मुश्किल होता है। –

+0

मैं सहमत हूं। मुझे बस यह सुनिश्चित करने की ज़रूरत है कि वेक्टर के तत्व हैं :-) – MBen

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