2016-01-19 9 views
5

यह कैसे है कि किसी प्रोग्राम में अभिव्यक्ति bad_alloc त्रुटि फेंक सकती है, इसके बावजूद कोई #include <new> नहीं है (क्योंकि यह त्रुटि is defined in the <new> header) है?<new> हेडर को परिभाषित नहीं किए जाने के बावजूद bad_alloc फेंकता है?

3.7.4 से। N3337:

लाइब्रेरी वैश्विक आवंटन और विध्वंस कार्यों के लिए डिफ़ॉल्ट परिभाषा प्रदान करती है। कुछ वैश्विक आवंटन और विध्वंस कार्यों को बदलने योग्य (18.6.1) हैं। एक सी ++ कार्यक्रम एक प्रतिस्थापन आवंटन या deallocation समारोह की एक परिभाषा प्रदान करेगा। ऐसी कोई फ़ंक्शन परिभाषा लाइब्रेरी में प्रदान किए गए डिफ़ॉल्ट संस्करण को प्रतिस्थापित करती है (17.6.4.6)। निम्नलिखित आवंटन और विध्वंस कार्यों (18.6) को कार्यक्रम के प्रत्येक अनुवाद इकाई में वैश्विक दायरे में स्पष्ट रूप से घोषित किया जाता है।

void* operator new(std::size_t); 

void* operator new[](std::size_t); 

void operator delete(void*); 

void operator delete[](void*); 

ये निहित घोषणाओं केवल फ़ंक्शन नाम operator new, operator new[], operator delete, और operator delete[] परिचय। [नोट: निहित घोषणाएं std, std::size_t, या किसी भी अन्य नाम का नाम नहीं देती हैं जो लाइब्रेरी इन नामों को घोषित करने के लिए उपयोग करती है। इस प्रकार, एक नई अभिव्यक्ति, हटा-अभिव्यक्ति या फ़ंक्शन कॉल जो हेडर <new> सहित बिना किसी फ़ंक्शन को संदर्भित करती है, अच्छी तरह से बनाई गई है। हालांकि, std या std::size_t का जिक्र करना बीमार है जब तक उचित शीर्षक सहित नाम घोषित नहीं किया जाता है। अंत ध्यान दें] आवंटन और/या आवंटन रद्द कार्य भी घोषित किया जा सकता है और किसी भी वर्ग

इस के लिए परिभाषित अभी भी मेरे लिए स्पष्ट नहीं है। निहित घोषणापत्र std::size_t का उपयोग करते हैं लेकिन उन्हें पेश नहीं करते हैं (और यह bad_alloc के मामले में होना चाहिए)? और को new अभिव्यक्ति से पहले पेश करने की आवश्यकता नहीं है? क्या यह समझ सकता है कि यह कैसा है, या क्या मुझे इसे अंकित मूल्य पर लेना है?

+1

ठीक है, आप मानक सी ++ लाइब्रेरी से जुड़ रहे हैं, जिसमें '' शामिल है, और इसलिए 'std :: bad_alloc' के बारे में पता है। –

+0

इस तथ्य के साथ कुछ करने के लिए कुछ हो सकता है कि एक सी ++ मानक शीर्षलेख आधिकारिक तौर पर किसी अन्य सी ++ मानक शीर्षलेख को शामिल करने की अनुमति है, लेकिन मुझे लगता है कि जहां तक ​​इन कार्यों का संबंध है, पूरी कहानी नहीं है। –

+0

कुछ प्रयोग करने के बाद, मैंने निष्कर्ष निकाला कि यह वास्तव में मामला है। मैं इसके बारे में एक जवाब लिखूंगा। –

उत्तर

4

आपका बोली का कहना है कि विश्व के उन कार्यों मौजूद हैं और के रूप में वर्णित परोक्ष घोषणा की जाती है। इस प्रकार जब आप new का आह्वान करते हैं, तो मानक लाइब्रेरी में वैश्विक फ़ंक्शन को कॉल किया जाता है। वैश्विक फ़ंक्शन new का कार्यान्वयन std::bad_alloc फेंकने वाला है, और संकलन के समय उस कार्यान्वयन के पास <new> तक पहुंच थी, इस प्रकार std::bad_alloc को फेंकना है। आपके कोड को यह जानने की आवश्यकता नहीं है कि std::bad_alloc क्या है, जब तक कि आप इसे पकड़ने की कोशिश नहीं कर रहे हों। लेकिन इसे पकड़ने के अलावा, ऐसा लगता है कि आप किसी अन्य फ़ंक्शन को किसी अन्य लाइब्रेरी से कॉल करते हैं जो कुछ मनमाने ढंग से अपवाद फेंक सकता है। आपको उस अपवाद के ब्योरे के बारे में जानने की आवश्यकता नहीं है जब तक कि आप इसे पकड़ने की कोशिश नहीं कर रहे हैं, लेकिन यह कैली को फेंकने में सक्षम होने से नहीं रोकता है।

+0

मैंने सोचा कि किसी भी प्रोग्राम का उपयोग मानक लाइब्रेरी से आता है जिसमें '# include' हेडर होना चाहिए? तो 'नई' और 'हटाएं' कार्यों की इन परिभाषाओं को खोजने के लिए मानक पुस्तकालय की निहित पहुंच है? यहां तक ​​कि एक न्यूनतम न्यूनतम कार्यक्रम जैसे 'int main() {}' को अभी भी मानक लाइब्रेरी तक पहुंच की आवश्यकता है? – SergeantPenguin

+0

@ सर्जेंट पेंगुइन थोड़ा और नाटकीय पाने के लिए, जब आप 'नया' कहते हैं, तो आप सीधे मानक लाइब्रेरी का आविष्कार नहीं कर रहे हैं। 'नई' एक भाषा की बात है। 'नई' करने की लाइन के साथ कहीं भी, भाषा वैश्विक आवंटन फ़ंक्शन को कॉल करने का वास्तविक कारण प्राप्त करने के लिए कॉल करेगी, जिसमें ऑब्जेक्ट निवास करेगा (संभवतः उस स्मृति में वस्तु के निर्माता को आविष्कार करने वाली भाषा के बाद) । मानक लाइब्रेरी एक डिफ़ॉल्ट वैश्विक आवंटन फ़ंक्शन प्रदान करती है (निर्दिष्ट फ़ंक्शन हस्ताक्षर के साथ ताकि लिंकर इसे ढूंढ सके) ताकि आपको स्वयं को लिखना न पड़े। –

4

नाम std::size_t नाम किसी अन्य पूर्णांक प्रकार के लिए सिर्फ एक टाइपिफ़ है, शायद unsigned long या unsigned long long। संकलक new के लिए असली पैरामीटर प्रकार जानता है, भले ही नाम size_t दिखाई नहीं दे रहा है।

bad_alloc लिए इसी तरह के। bad_alloc फेंकने वाले रनटाइम कोड में निश्चित रूप से <new> शीर्षलेख शामिल है, भले ही आपका प्रोग्राम न हो।

3

ए सी ++ मानक शीर्षलेख को किसी अन्य सी ++ हेडर को शामिल करने की अनुमति है। इसलिए आप और <cstddef> एट अल सहित std::size_t को <new> को शामिल किए बिना std::bad_alloc के कार्यान्वयन पर निर्भर उपयोग कर सकते हैं,। मैं भी मानक के अपने संस्करण में उसे ढूंढने की आलसी हूँ, लेकिन N4296 मसौदे में यह §17.6.5.2 में बताया गया है:

एक C++ शीर्ष लेख अन्य सी ++ हैडर शामिल कर सकते।

आप एक संकलक के साथ इस कोशिश कर सकते हैं।

int main() 
{ 
    std::size_t x; // error 
    std::bad_alloc y; // error 
} 

अब पूरी तरह से असंबद्ध #include जोड़ें:

#include <complex> 

int main() 
{ 
    std::size_t x; // probably not an error anymore, depends on compiler 
    std::bad_alloc y; // probably not an error anymore, depends on compiler 
} 
संबंधित मुद्दे