2013-02-05 13 views
6

मेरा एक प्रोग्राम std::out_of_range फेंकता है। मुझे इसके कारण पता है, मैं कहीं भी इंडेक्स -1 के साथ एक वेक्टर तक पहुंच रहा हूं। जो मुझे नहीं पता वह कोड में वेक्टर (चर नाम) और स्थान का नाम है। त्रुटि मेरा कार्यक्रम द्वारा उत्पादित संदेश इस प्रकार है:ऑब्जेक्ट फेंकना std :: out_of_range

terminate called after throwing an instance of 'std::out_of_range' 
    what(): vector::_M_range_check 
zsh: abort (core dumped) ./main.x config.cfg 

वहीं कुछ अन्य पुरुष के कोड से तैयार की त्रुटि संदेश (वह g++ का उपयोग करता है भी) और सवाल C++ accessing vector में तैनात इस तरह दिखता है:

Error for vec.at(i).setVec(tmp); 
Error is: terminate called after throwing an instance of 'std::out_of_range' 
    what(): vector::_M_range_check 

आईई उसे चर के नाम से कहा जाता है। मेरा सवाल है:

क्या मुझे विस्तारित जानकारी देने के लिए g++/gcc बताने का कोई तरीका है? हो सकता है कि लाइन नंबर भी शामिल हों (पता नहीं कि यह संभव है लेकिन हे, एक लड़का सपना देख सकता है;))।
बस funsies के लिए मैंने विकल्प के साथ gdb में अपना प्रोग्राम चलाया (मैं जोड़ सकता हूं, मेरे पास एक वास्तविक डीबगर का उपयोग करने में शून्य अनुभव है) जिसने मुझे कुछ भी नया नहीं बताया, वास्तव में, यह मुझे नहीं बताया कि त्रुटि std::out_of_range अपवाद के कारण थी।

Btw, मेरे संकलक झंडे (डिबग के लिए) इस प्रकार हैं:

CFLAGS = --exceptions -I$(ROOTSYS)/include --std=c++11 -Wall -g -O0 -fno-inline -fno-eliminate-unused-debug-types 
+9

'पकड़ फेंक' के साथ 'gdb' चलाने के बाद, जब अपवाद पकड़ा जाता है, तो 'कहां' टाइप करें। –

+0

@ डेविडस्वार्टज़ बिल्कुल सही! तो अब मुझे 'gdb' से लाइन नंबर मिल गया है, दूसरा त्रुटि संदेश प्राप्त करने का कोई मौका (यानी डीबगर के बिना नाम)? – elemakil

उत्तर

3

ब्रेकपॉइंट मारने के बाद gdb shell में bt (backtrace) कमांड दर्ज करें। यह स्टैक ट्रेस (त्रुटि की ओर अग्रसर फ़ंक्शन कॉल का अनुक्रम) प्रिंट करेगा।

परिवर्तनीय नाम प्राप्त करने के लिए अब आप स्टैक में ऊपर की ओर नेविगेट करने के लिए up कमांड का उपयोग कर सकते हैं और उन कार्यों में से प्रत्येक में उपयोग किए जाने वाले चर को देख सकते हैं।

+0

यह स्टैक के शीर्ष पर जाने के बाद अपेक्षाकृत काम करता है (यानी एकाधिक 'अप' कमांड) दोषपूर्ण कोड वाली रेखा मुद्रित होती है। – elemakil

3

std::out_of_range::out_of_range पर एक ब्रेकपाइंट रखो। एक अपवाद ऑब्जेक्ट, जैसे सभी सी ++ ऑब्जेक्ट्स, इसके कन्स्ट्रक्टर के बाहर निकलने के बाद अपना जीवन शुरू करता है।

[संपादित करें] टिप्पणी ने यह स्पष्ट किया: std::out_of_range::what() द्वारा उत्पादित स्ट्रिंग समस्या। यह कार्यान्वयन-परिभाषित है। जाहिर है, आपके मामले में यह __FUNCTION__ से बना है, एक जीसीसी मैक्रो जो वर्तमान (यानी फेंकने) फ़ंक्शन का नाम देता है। लेकिन इस तरह का एक समारोह केवल this जानता है, यानि वर्तमान वस्तु के सूचक और न कि उसका नाम। दूसरे मामले में, ऑब्जेक्ट का नाम किसी अन्य विधि के माध्यम से पुनर्प्राप्त किया जाता है, std::out_of_range::what() नहीं।

+0

मुझे लगता है कि आप का मतलब है कि मैं एप्लिकेशन को निष्पादित करने से पहले 'gdb' में' break std :: out_of_range :: out_of_range' निष्पादित करता हूं (यानी 'run' run')। केवल ऐसा करने के लिए 'कैच फेंक' के समान प्रभाव पड़ता है, इस प्रकार ब्रेकपॉइंट के बाद 'कहां' जारी किया जाता है (जैसा कि @ डेविडस्वार्टज़ द्वारा सुझाया गया है) लाइन नंबर दिखाता है। हालांकि, उनके समाधान के समान इसमें एक डीबगर का उपयोग करना शामिल है, है ना? यही कहना है कि इस विधि का उपयोग करके दूसरा त्रुटि संदेश प्राप्त नहीं किया जा सकता है। – elemakil

+0

मुझे लगता है कि ऑब्जेक्ट्स नाम प्रिंट करने की कार्यक्षमता जोड़ने का कोई आसान तरीका नहीं है? – elemakil

+0

@elemakil: नहीं, यह बात है। _does_ फेंकने वाला फ़ंक्शन ऑब्जेक्ट में 'यह' पॉइंटर जानता है, और उसका स्वयं का फ़ंक्शन नाम है, लेकिन ऑब्जेक्ट का नाम नहीं है। (दार्शनिक प्रश्न को छोड़कर क्या _the_ ऑब्जेक्ट नाम वैसे भी है - जो आम तौर पर कॉलस्टैक में कितना गहरा होता है इस पर निर्भर करता है)। – MSalters

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