2013-01-03 24 views
19

जावा और सी # और शायद कई अन्य भाषाओं के बराबर है, तो एक पूर्वनिर्धारित अपवाद वर्ग है जिसे एक शून्य पैरामीटर का उपयोग किया जाता है, जहां इसे नहीं किया जाना चाहिए। क्या सी ++ में कुछ भी समान है? यदि नहीं, तो क्या कोई और पूर्वनिर्धारित अपवाद है जिसका मैं उपयोग कर सकता हूं या क्या मुझे अपना खुद का परिभाषित करना चाहिए?क्या कोई C++ एक NullPointerException

+9

सेगमेंटेशन फॉल्ट। – kmkaplan

+0

एफटीआर, सी # में आप कुछ भी के लिए NullReferenceExceptions का उपयोग नहीं करते हैं जब तक कि आप अपने टीम के साथी द्वारा छेड़छाड़ नहीं करना चाहते हैं। –

+0

सी # में मैं एक ArgumentNullException का उपयोग करता हूं और मेरी टीम के साथी हमेशा मेरे लिए अच्छे होते हैं। –

उत्तर

20

एक पूर्ण सूचक का निर्धारण करना C++ में अपरिभाषित व्यवहार है - जिसका अर्थ है कि कोड काम पर दिखाई दे सकता है। एक अपवाद फेंकने की गारंटी नहीं है। आप

std::invalid_argument

अपवाद उपयोग कर सकते हैं (यह करने के लिए एक सार्थक मूल्य प्रदान - "p is NULL"), लेकिन आप अपने आप को चेक करना होगा।

+0

धन्यवाद, यह वह उत्तर है जिसे मैं ढूंढ रहा था। –

9

आमतौर पर, सी ++ (या उस मामले के लिए सी) में, आप कभी एक पूर्ण सूचक को अस्वीकार करते हैं। ऐसा करने के लिए अपरिभाषित व्यवहार (संभवतः किसी भी कार्यान्वयन पर एक segfault मुझे पता है, लेकिन मानक के अनुसार कुछ भी हो सकता है)। यह शायद अन्य भाषाओं में भी एक बुरी चीज है, लेकिन मैं उनको ज़ोर देने के लिए पर्याप्त नहीं जानता।

इससे पुनर्प्राप्त करने की कोशिश करने से स्थिति को रोकने के लिए सबसे अच्छा है (जिसे सी या सी ++ में भी नहीं किया जा सकता है)।

int foo(int* myint) 
{ 
    // Ensure myint is not NULL 
    assert(myint); 

    // Do something with myint 
    (*myint)++; 

    return *myint; 
} 

इस तरह assert() कॉल पूरी तरह से रिलीज पर ध्यान नहीं दिया जाता बनाता है और इस प्रकार उत्पादन में कोई कीमत है:

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

+5

आमतौर पर सी # एन जावा में यह नल पॉइंटर्स को पकड़ने पर भरोसा करना भी बुरा व्यवहार है (केवल अपवाद है सभी रनटाइम अपवादों से बहुत उच्च स्तर की वसूली, उदाहरण के लिए थ्रेड पूल में)। वे प्रोग्रामिंग त्रुटियों को ढूंढना आसान बनाने के लिए हैं। – Thirler

+0

ध्यान रखें कि अगर कोड एनडीईबीयूजी परिभाषित (-DNDEBUG) के साथ संकलित किया जाता है तो assert() # ifdef'd होगा। – daddesio

4

एफटीआर, सी # में आप NullReferenceException एस का उपयोग तब तक नहीं करते जब तक आप अपने टीम के साथी द्वारा छेड़छाड़ नहीं करना चाहते। शून्य तर्कों को अस्वीकार करने के लिए ArgumentNullException है। एनआरई रनटाइम द्वारा फेंकने के लिए हैं, न कि आप।

लेकिन ध्यान दें कि इस पर कोई प्रभाव नहीं है क्योंकि आपको इनमें से किसी एक को पकड़ना नहीं चाहिए: अगर उन्हें फेंक दिया जाता है, तो वे एक बग इंगित करते हैं। ये एरिक लिपर्ट boneheaded exceptions पर कॉल करते हैं और वे आपकी खुद की डर्न गलती हैं, और आपके कोड को विशेष रूप से उनके साथ कुछ भी नहीं करना चाहिए।

2

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

2

लगभग सभी मामलों में जो एक शून्य सूचक (esp।, इसे अपमानित) का उपयोग करके गलत तरीके से शामिल करते हैं, सी ++ मानक केवल व्यवहार को अपरिभाषित छोड़ देता है। के लिए कोई विशिष्ट अपवाद प्रकार प्रदान नहीं किया गया है (और कोई अपवाद नहीं फेंक दिया जाएगा)।

हालांकि, इस नियम के लिए एक संभावित अपवाद दिमाग में आता है।std::function है, जो कि कार्यों रैप करने के लिए इस्तेमाल किया जा सकता एक सी ++ 11 मानक-पुस्तकालय टेम्पलेट है, एक अशक्त सूचक सौंपा जा सकता है:

std::function<void(int)> func = nullptr; 

और अगर आप तब तक समारोह में यह द्वारा लिपटे कॉल करने के लिए एक प्रयास कर कुछ तर्क arg के लिए func(arg); कर रहा है, यह std::bad_function_call अपवाद फेंक देगा।

यह वह जगह है, जाहिर है, पूरी तरह से, अन्य भाषाओं के नल पॉइंटर अपवाद के बराबर नहीं है, क्योंकि यह अब तक कम आम तौर पर लागू होता है।

5

एक पूर्ण सूचक को डिफ्रेंस करने के लिए सी ++ में कोई मानक अपवाद नहीं है।

यदि आप इसे चाहते हैं, तो आप इसे स्वयं लागू कर सकते हैं। यूनिक्स पर एक एसआईजीएसईजीवी सिग्नल हैंडलर स्थापित किया गया और हैंडलर से अपवाद फेंक दिया। विंडोज़ पर, "संरचित अपवाद" हैंडलर स्थापित करने के लिए _set_se_translator() API का उपयोग करें।