2011-10-05 28 views
8

मेरे पास एक कोड है जहां मैं कुछ डेटाबॉक तक पहुंचने के लिए पॉइंटर का उपयोग करता हूं। कुछ दुर्लभ मामलों में, डेटाबॉक के कुछ सदस्य खाली होते हैं, और नतीजतन पॉइंटर खतरनाक हो जाता है। वास्तव में, मुझे सही सूचक मिलता है लेकिन पॉइंटर के साथ कुछ करने का प्रयास करते समय प्रोग्राम क्रैश हो जाता है।क्या यह जांचने का कोई तरीका है कि पॉइंटर खतरे में है या नहीं?

सामान्य सलाह इस प्रकार के उपयोग से बचने के लिए होगी। लेकिन दुख की बात है कि, मेरे द्वारा उपयोग किए जाने वाले ढांचे के लिए आवश्यक है कि मैं इस प्रकार के डेटा एक्सेस विधियों का उपयोग करूं।

क्या कोई तरीका है यदि मैं इसके साथ कोई ऑपरेशन करने से पहले पॉइंटर अमान्य हो तो "जांच" कर सकता हूं? यह जांचकर कि सूचक न्यूल के बराबर नहीं है, जाहिर है। मैंने यह भी कोशिश की:

try 
{ 
    CString csClassName = typeid(*pMyPointer).name(); // Check error condition 
    // The line below fails due to dangling pointer (data block is not valid). 
    hr = pMyPointer->MyPointerMethod(); 
} 
catch(bad_typeid) 
{ 
    return E_FAIL; 
} 
catch(...) 
{ 
    return E_FAIL; 
} 

क्या यह सही तरीका है?

उत्तर

5

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

+0

मेरा सूचक कक्षा में स्थिर होना चाहिए..यह अभी भी ठीक है अगर मैं स्मार्ट पॉइंटर्स का उपयोग करता हूं? – Nikhil

+0

यह कोई समस्या नहीं है। आपको थ्रेड सुरक्षा समस्याओं के लिए बाहर देखने की आवश्यकता है, लेकिन यह एक कच्चे सूचक के रूप में एक स्मार्ट सूचक के लिए अलग नहीं है। –

+2

मुझे नहीं लगता कि यह महत्वपूर्ण है। केवल एक चीज जो मुझे परेशान करती है वह यह है कि क्या आपका ढांचा स्वयं को बिना किसी पूर्व सूचना के अपने पॉइंटर्स को लटक सकता है। देखें, आपको स्मार्ट पॉइंटर से कच्चे पॉइंटर निकालना होगा और इसे अपने ढांचे में पास करना होगा। यदि यह गारंटी देता है कि कॉलर कॉल के बाद वैध रहेगा, या आपको सूचित किया जाएगा कि यह अमान्य हो जाना चाहिए - ठीक है, इसके लिए जाएं। – Septagram

7

मुझे लगता है कि आप गलत दिशा को देख रहे हैं। आपके पास शायद एक बग है जिसके द्वारा आप पॉइंटर्स को सही ढंग से प्रारंभ नहीं कर रहे हैं, ऑब्जेक्ट्स को बहुत जल्दी हटा रहे हैं और इसे हटाए जाने के बाद पॉइंटर का पुन: उपयोग करने की कोशिश कर रहे हैं या कुछ समान है। यदि ऐसा है, तो आपको यह निर्धारित करने पर ध्यान देना चाहिए कि यह क्यों हो रहा है और बग को छिपाने का तरीका खोजने के बजाय बग को ठीक करना है।

typeid ऑपरेटर के साथ आप जिस दृष्टिकोण का उपयोग कर रहे हैं, उसका जवाब यह है कि यह मान्य नहीं है। उन प्रकारों की वस्तुओं के लिए जिनमें वर्चुअल फ़ंक्शंस नहीं हैं, typeid ऑपरेटर को पॉइंटर के स्थिर प्रकार के आधार पर संकलित समय पर हल किया जाता है। कम से कम एक वर्चुअल फ़ंक्शन वाले ऑब्जेक्ट्स के लिए, इसे रनटाइम पर हल किया जाता है, लेकिन typeid(p) को अमान्य पॉइंटर के साथ कॉल करना अनिर्धारित व्यवहार है, और उसी तरह यह काम करने लगता है, यह क्रैश हो सकता है।

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

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

+0

आपके विस्तृत स्पष्टीकरण के लिए धन्यवाद। मैं समझ सकता हूं कि मुझे बग को छिपाने के बजाय समाधान मिलना चाहिए ... लेकिन ढांचे में एक छेड़छाड़ है जिसे मैं कम समय में नहीं बदल सकता। इसलिए मैं समय के लिए कामकाज की तलाश में था मैंने स्मार्ट पॉइंटर्स के साथ भी कोशिश की लेकिन यह काम नहीं कर सका। – Nikhil

1

आपको स्मार्ट पॉइंटर्स की आवश्यकता नहीं है। वे इस समस्या से निपटने के लिए सिर्फ एक संभावित दृष्टिकोण हैं।

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

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

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