2010-03-05 12 views
11

एसटीएल :: वेक्टर के साथ:को अक्षम करने से सीमा ग के लिए जाँच ++ वैक्टर

vector<int> v(1); 
v[0]=1; // No bounds checking 
v.at(0)=1; // Bounds checking 

सभी at()[] के रूप में फिर से लिखने के बिना सीमा जाँच निष्क्रिय करने के लिए कोई तरीका है? मैं जीएनयू मानक सी ++ लाइब्रेरी का उपयोग कर रहा हूं।

संपादित: मैं ऐसा क्षेत्र है जहां मैं एक टोंटी संदिग्ध में [] करने के लिए at() बदल गया है, और यह काफी गणना समय कम कर दिया। हालांकि, चूंकि मैं कोड विकसित करने और इसके साथ प्रयोग चलाने के बीच पुनरावृत्ति करता हूं, इसलिए मैं विकास के दौरान सीमाओं की जांच को सक्षम करना चाहता हूं और जब मैं वास्तविक प्रयोगों को चलाता हूं तो इसे अक्षम कर देता हूं। मुझे लगता है कि एंड्रयू की सलाह सबसे अच्छा समाधान है।

+6

क्या अंत करने के लिए? एक बेहतर तरीका हो सकता है। –

+0

आपको '(]' के साथ 'at()' को प्रतिस्थापित करने के लिए नियमित अभिव्यक्ति का उपयोग करने में सक्षम होना चाहिए, और यह सत्यापित करने में सहायता के लिए ब्रेकपॉइंट सेट करें कि सभी उदाहरण प्रतिस्थापित किए गए हैं। ऐसा नहीं है कि एक फिसलने से आपदा हो जाएगी, चिंता सिर्फ प्रदर्शन है, है ना? – Potatoswatter

+4

आप ऐसा क्यों करना चाहते हैं? यदि आपका उत्तर प्रदर्शन है, तो कृपया मुझे बताएं कि आपने प्रोफाइल किया है और पाया है कि यह आपकी बाधा है। यदि ऐसा है, तो हाँ, अपने() s को '[] 'के रूप में पुनः लिखें। अन्यथा, इसे होने दो। –

उत्तर

15

नहीं std::vector::at की सीमा-जांच मानक द्वारा निर्दिष्ट है, और कोई मानक-अनुरूप सी ++ कार्यान्वयन नहीं है जो उससे विचलित हो सकता है।

3

मानक तरीका नहीं है। आप अपने कंपाइलर में अपवाद बंद कर सकते हैं। आप इसे -fno-exceptions के साथ जीसीसी के साथ कर सकते हैं।

आपको ऐसा करने से सावधान रहना चाहिए; आपके पुस्तकालय (मानक पुस्तकालयों सहित) अपवादों के साथ अच्छी तरह से खेल नहीं सकते हैं। अपने दस्तावेज़, और this one on the gcc mailing list जैसे धागे की जांच करें।

+0

मुझे नहीं लगता कि यह एक अच्छा दृष्टिकोण है लेकिन लिंक के लिए +1 है। – Potatoswatter

6

शायद बेहतर समाधान [] का उपयोग करना है और डीबग के लिए मानक लाइब्रेरी के चेक कार्यान्वयन का उपयोग करना है।

23

तुम सच में यह (एक त्वरित और गंदा रूपरेखा तुलना के लिए कम से कम), यह अगर आपके पास काम करेंगे करना चाहते हैं तो कोई अन्य at() रों

#define at(x) operator[](x) 

और आप विकास के लिए at() रखना चाहते हैं और उत्पादन में operator[] का उपयोग करें, बस इसे #ifdef पर लपेटें।

और यदि आपके पास अन्य at() है तो आप हमेशा अपने #include डी <vector> फ़ाइल को संपादित कर सकते हैं।

+0

+1 पार्टी के लिए देर हो चुकी है, लेकिन उत्कृष्ट सलाह दे रही है। यह निश्चित रूप से कुछ प्रोफाइल करने के लिए त्वरित और गंदा तरीका है। –

+0

+1 यह मेरा सुझाव होगा – imallett

0

आप यथोचित संगत पहुँच पैटर्न (यानी/नहीं रैंडम एक्सेस), बल्कि at() या [], एक दृष्टिकोण का उपयोग कर सीमा की जाँच से बचने के लिए iterators उपयोग करने के लिए किया जाता है की तुलना में, के माध्यम से भी बेहतर begin(), end(), और advance() या का उपयोग करते हुए, है, तो मानक एल्गोरिदम का उपयोग।

3

बनाता है की अपनी टिप्पणी है कि आप चालू करने के लिए चाहते हैं के आधार पर

हालांकि यह सही करने at() रेंज मानक पुस्तकालय (MSVC) के कुछ कार्यान्वयन की जाँच करने की मूल समस्या का समाधान नहीं होता कुछ प्रकार के iterators जाँच कर ली है/बंद सीमा जाँच, आप एक आवरण टेम्पलेट समारोह इस्तेमाल कर सकते हैं:

template <class T> 
inline typename T::reference deref(T &cont, typename T::size_type idx) 
{ 
#if BOUNDS_CHECK 
    return cont.at(idx); 
#else 
    return cont[idx]; 
#endif 
} 

template <class T> 
inline typename T::const_reference deref(const T &cont, typename T::size_type idx) 
{ 
#if BOUNDS_CHECK 
    return cont.at(idx); 
#else 
    return cont[idx]; 
#endif 
} 

आप इसे सक्षम करने के लिए अपने कोड को संशोधित करने के लिए होता है, लेकिन एक बार आप इसे जगह में था आप चालू या बंद के रूप में आप चाहते हैं की जाँच के लिए बाध्य कर सकता है ।

मैं मानता है कि यह थोड़ा बदसूरत उपयोग करने के लिए लग रहा है:

deref(vec, 10) = ...; 
2

की तरह "uncheckedvector" अपनी खुद की नाम स्थान में अपने स्वयं के वेक्टर वर्ग प्राप्त है, और उपयोग करने के लिए आधार वेक्टर प्रकार के कम से ओवरराइड() सरणी सूचकांक।

फिर "अनचेकवेक्टर :: वेक्टर" का उपयोग करके आप हर जगह वेक्टर के अपने सभी उपयोगों को ओवरराइड करने देंगे। यदि आप कहीं भी पूरी तरह से योग्य प्रकार का उपयोग कर रहे हैं तो यह काम नहीं करेगा।

+0

-1: कभी भी एसटीएल प्रकारों से प्राप्त नहीं होता है, उनमें वर्चुअल विनाशकों की कमी होती है। – Joh

2

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

[] के लिए जाँच जब लिनक्स पर जीसीसी का उपयोग कर विकास मोड सीमा के तरीकों में से एक जोड़े:

  • GCC debug mode सक्षम करें, यह भी GCC STL bound checking

    -D_GLIBCXX_DEBUG

  • देखने के तहत अपने कार्यक्रम चलाएं Valgrind मेमोरी चेकर

    valgrind (your program and args)

कुछ अन्य रोचक चर्चा: vector::at vs. vector::operator[]

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