2008-10-17 4 views
5

मैं एक एमएफसी ऐप के लिए एक बड़े, उम्र बढ़ने कोड बेस पर काम कर रहा हूं। समय के साथ कई डेवलपर्स द्वारा कोड पर काम किया गया है, और नतीजतन, हमारे पास नए के साथ आवंटन विफलता की संभावना से निपटने के पूरे कोड में तीन अलग-अलग तरीके हैं।एमएफसी के बिना सी ++ स्थिर पुस्तकालय जो एमएफसी प्रोजेक्ट से जुड़े हैं bad_alloc या CMemoryException * फेंक दें?

पहला तरीका न्यू के परिणामस्वरूप न्यूल के लिए परीक्षण करना है। हम nothrownew.obj का उपयोग नहीं करते हैं, इसलिए यह स्पष्ट रूप से एक त्रुटि है जिसे साफ़ करने की आवश्यकता है।

दूसरा सीएममोरी अपवाद * पकड़ने के लिए है (हाँ, संकलक में सी ++ अपवाद सक्षम हैं)। जो मैं समझता हूं, एमएफसी मानक ऑपरेटर को ओवरराइड करता है, और इसके बजाए इस चीज़ को फेंकता है। मैं काफी हद तक निश्चित हूं कि यह दूसरी विधि एमएफसी एप्लिकेशन में ही सही है। एमएफसी अपने अजीब CMemoryException फेंकने संस्करण के साथ, नए ओवरराइड करता है।

आखिरी बार हमारे लोगों के आधार पर आता है जो सी ++ के साथ अच्छे हैं, लेकिन एमएफसी प्रोग्रामर नहीं हैं। वे कॉन्स std :: bad_alloc & पकड़ रहे हैं।

मुझे वास्तव में पता नहीं है कि एप्लिकेशन में जुड़े स्थिर पुस्तकालयों की अपेक्षा क्या है। यह कोड का विशाल बहुमत था जो bad_alloc जीवन का उपयोग करता है। इन पुस्तकालयों को मानना ​​एमएफसी या एटीएल के साथ संकलित नहीं है, और केवल मानक सी ++ में लिखे गए हैं, क्या वे bad_alloc को पकड़ने की उम्मीद कर सकते हैं? या एमएफसी की उपस्थिति में वे वैश्विक नए ऑपरेटर के साथ उन्हें संक्रमित करने के लिए लिंक करेंगे और खराब आवंटन म्यूट पर साफ-सफाई में विफल होने के अपने प्रयास प्रस्तुत करेंगे?

यदि आपके पास कोई जवाब है, तो क्या आप यह बता सकते हैं कि यह कैसे काम करता है, या मुझे इसे हल करने के लिए सही संदर्भ में इंगित करता है?

उत्तर

3

यह स्थिर पुस्तकालयों से जुड़े होने के संकलन विकल्पों पर निर्भर करेगा आवेदन पत्र।

पुस्तकालयों एक विन्यास स्थिर स्टैंडर्ड सी उपयोग करने के लिए रन-टाइम ++ के साथ संकलित रहे हैं तो मैं रन-टाइम ++ स्टैंडर्ड सी से operator new उम्मीद होती है कहा जाता है।

पुस्तकालयों एक विन्यास स्टैंडर्ड सी उपयोग करने के लिए रन-टाइम ++ तो DLL इन कार्यों के संकल्प कार्यक्रम लोड जब तक विलंब होगा और operator new की MFC प्रतिस्थापन को सुलझाया जाना चाहिए के साथ संकलित कर रहे हैं।

मैंने इस हर्ब सटर article के लिए एक लिंक भी शामिल किया है जो आवंटन त्रुटियों को संभालने के संबंध में उपयोगी है।

+0

धन्यवाद! हम डीएलएल के रूप में मानक सी ++ रनटाइम से लिंक करते हैं, जिसका मतलब है कि सभी के लिए एमएफसी अपवाद। दुर्भाग्यवश, इस ऐप के प्रमुख लक्ष्यों में से एक वर्चुअल मेमोरी के बिना एक सिस्टम है, इसलिए आवंटन जांच की आवश्यकता है, ओह। –

+0

यदि आप प्रतीकों के साथ संकलित करने में सक्षम हैं तो मैं ऑपरेटर को कॉल में कदम उठाने का सुझाव दूंगा और डीबगर को निश्चित रूप से साबित करना चाहिए कि कार्यान्वयन कहलाया जा रहा है। सुनिश्चित नहीं है कि यह आपके लक्षित प्लेटफार्म के लिए उपयोगी है .. – Henk

+0

प्रतीक कोई समस्या नहीं है। शाखा को अपवाद फेंकने के लिए मजबूर करना, विशेष रूप से दिखाता है कि सीमेंरीएक्सप्शन * फेंक दिया जा रहा है। यह चीजों को एक स्पर्श को जटिल बनाता है, लेकिन यह जानना अच्छा होता है कि वास्तव में क्या चल रहा है। एक बार फिर धन्यवाद! –

1

बधाई हो - आपको लगता है कि हम सभी ने हमला किया है। :-)

सिद्धांत रूप में, यदि एमएफसी वैश्विक new फ़ंक्शन के लिए अधिभार प्रदान करता है, तो इसे प्रोग्राम में सभी कोड द्वारा उपयोग किया जाना चाहिए। लेकिन चूंकि स्थिर पुस्तकालयों को इसके बारे में जानने के बिना संकलित किया गया था, इसलिए मैं निश्चित रूप से यह नहीं कह सकता कि यह होगा।

सबसे अच्छा मैं सुझाव दे सकता हूं कि पता लगाने के लिए कुछ परीक्षण कोड लिखना है। (मुझे अगले कुछ घंटों तक अपने विंडोज सिस्टम तक पहुंच नहीं होगी, या मैं खुद ऐसा करूँगा और आपको जवाब दूंगा।)

+0

यह मेरे साथियों को भी फेंक दिया, और कोई भी अच्छे तरीके से नहीं आ सकता पहले स्थान पर नए अधिभार के बिना नए असफल होने के लिए मजबूर होना। Arg :) –

0

आप एमएफसी फेंकिंग व्यवहार को AfxSetNewHandler(_PNH pfnNewHandler) के साथ बदल सकते हैं और अपने NewHandler फ़ंक्शन पर पॉइंटर प्रदान कर सकते हैं। इस फ़ंक्शन को std::bad_alloc अपवाद फेंकना चाहिए। लेकिन अब एमएफसी-प्रोग्राम-पार्ट्स को std::bad_alloc पकड़ने में समस्या है।

1

मैंने कुछ एमएफसी-कोड-शोध (वीसी -2010 में) किया है। यहां कुछ तथ्य हैं।

  1. MFC "_simpleMemoryException" नामक एक वैश्विक CMemoryException उदाहरण के लिए सूचक फेंकता है (यह भी AfxThrowMemoryException देख())
  2. यह एक CException जिसका m_bAutoDelete झूठी है।

विचार: यह संभव C++ बदलने के लिए है - केवल स्थैतिक-पुस्तकालयों, आप रूट नेम स्पेस में class CException; और/या class CMemoryException; घोषित अग्रेषित कर सकते हैं।

catch (CMemoryException* pEx) {...} और/या catch (CException* pEx) {...} के साथ एक कैच-ब्लॉक जोड़ें जहां प्रत्येक स्थान पर std::bad_alloc-catch ब्लॉक है। चूंकि कैच किए गए पॉइंटर वैश्विक ऑब्जेक्ट के लिए पॉइंटर है, इसलिए pEx->Delete(); पर कॉल करने की आवश्यकता नहीं है।

इस तरह सी ++ - केवल-स्थैतिक-पुस्तकालयों में afx.h या/और एमएफसी के खिलाफ लिंक शामिल करने की आवश्यकता नहीं है। मैंने इसे VC2010 में आजमाया है, और यह ठीक काम करता है। (केवल अगर आरटीटीआई सक्षम है, और केवल अगर कोई भी एमएफसी-न्यूहैंडलर को डिफ़ॉल्ट रूप से एमएफसी-न्यूहैंडलर AfxNewHandler से कुछ और करने के लिए एमएफसी-न्यूहैंडलर में बदलता है)

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