2011-07-01 23 views
5

पिछले कुछ दिनों में एक बहु-थ्रेडिंग को डिबग करने के दौरान, जहां एक धागा किसी ऑब्जेक्ट को किसी अन्य द्वारा उपयोग में ला रहा था, मुझे एहसास हुआ कि यह मुद्दा निदान करने के लिए बहुत आसान और त्वरित होगा अगर मैं 'यह' अस्थिर बना सकता। यह सिस्टम (सिम्बियन ओएस) पर क्रैश डंप को कहीं अधिक जानकारीपूर्ण में बदल देता।'यह' अस्थिर क्यों नहीं है?

तो, क्या ऐसा कोई कारण है कि यह क्यों नहीं हो सकता है, या नहीं होना चाहिए?

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

static TAny* gGlobalPointer = NULL; 

#define Harness static_cast<CSomeClass*>(gGlobalPointer); 

class CSomeClass : public CBase 
    { 
public: 
    static void DoSomething(); 

private: 
    int iMember; 
    }; 


void CSomeClass::DoSomething() 
    { 
    if (!Harness) 
     { 
     return; 
     } 

    Harness->iMember = 0; 
    } 

तो यदि कोई अन्य धागा हटा दिया गया है और वैश्विक सूचक को न्यूल किया गया है तो इसे तुरंत पकड़ा जाएगा।

एक मुद्दा जो मुझे लगता है कि यह है कि यदि संकलक हर बार इसे जांचने के बजाय हार्नेस के मूल्य को कैश करता है।

+0

क्या आपका मतलब यह है कि अगर यह अस्थिर था, तो यह आसान होगा, या यह आसान होगा अगर यह 'पॉइंटर-टू-अस्थिर था? दूसरे शब्दों में, क्या आप क्रैश डंप को 'इस' के पुराने मूल्य को देखते हुए देख रहे थे (जो कुछ अजीब लगता है क्योंकि यह कभी नहीं बदलेगा), या कुछ डेटा सदस्य? –

उत्तर

7

इस एक चर, लेकिन एक स्थिर नहीं है। आप द्वारा द्वारा संदर्भित ऑब्जेक्ट को बदल सकते हैं, लेकिन आप के के मान को नहीं बदल सकते हैं। क्योंकि स्थिरांक कभी नहीं बदलते हैं, उन्हें अस्थिर के रूप में चिह्नित करने की आवश्यकता नहीं है।

+1

और "निरंतर" से आपका मतलब है 'टी * कॉन्स' और 'const t *' नहीं। –

+2

उत्तर सी ++ शर्तों में वास्तव में समझ में नहीं आता है। 'यह' एक अभिव्यक्ति है। और 'const' अभिव्यक्ति निश्चित रूप से C++ में बदल सकती हैं:' int x = 0; int const * px = & x; std :: cout << * px; एक्स = 1; std :: cout << * px; '। – MSalters

+0

@ माइक नहीं, इसका मतलब यह नहीं है कि 'टी * कॉन्स' का अर्थ है 'टी *' जो कि एक वस्तु नहीं है। 'यह' const' बनाने के लिए यह समझ में नहीं आता है। खैर, कम से कम मुझे लगता है कि उसका मतलब है। अन्यथा उसका जवाब मुझे समझ में नहीं आता है! –

2

यह हो सकता है। बस सदस्य समारोह को अस्थिर घोषित करें।

struct a 
{ 
    void foo() volatile {} 
}; 
+1

और वास्तविक प्रश्न का उत्तर देने के लिए, डिफ़ॉल्ट रूप से ऐसा नहीं होने का कारण यह है कि आप 'यह' को पॉइंटर-टू-गैर-अस्थिर बनाने वाले फ़ंक्शन में पास नहीं कर पाएंगे। वही कारण 'यह' पॉइंटर-टू-कॉन्स नहीं है जब तक कि आप सदस्य फ़ंक्शन 'const' को चिह्नित न करें। –

2

अस्थिर आपकी मदद नहीं करेगा।
यह एक परिवर्तनीय अस्थिरता तक पहुंच बनाएगा, लेकिन पूरा करने के लिए किसी भी विधि की प्रतीक्षा नहीं करेगा।

स्मार्ट पॉइंटर्स का उपयोग करें।

shared_ptr

वहाँ भी नए C++ संस्करणों में एसटीडी में एक संस्करण है।

+0

सिम्बियन सी ++ में कोई स्मार्ट पॉइंटर्स नहीं है। मैं नहीं चाहता था कि यह सिंक्रनाइज़ेशन प्रदान करे, मैं एक बासी पॉइंटर तक पहुंचने पर क्रैश करना चाहता था। – James

+0

@ जेम्स: इसे अस्थिर बनाना इसे दुर्भाग्य से प्राप्त नहीं करेगा। –

+0

साझा पॉइंटर्स templted कक्षाएं हैं .. आप इसे dowonload कर सकते हैं और अपनी परियोजना –

4

यह मदद नहीं करेगा: एक परिवर्तनीय अस्थिर बनाने का मतलब है कि संकलक यह सुनिश्चित करेगा कि यह हर बार स्मृति से अपना मान पढ़ता है, लेकिन this का मान बदलता नहीं है, भले ही, किसी भिन्न संदर्भ से या वही, आप जिस वस्तु को इंगित कर रहे हैं उसे हटा दें।

+2

में जोड़ सकते हैं ...क्योंकि एक सूचक (विशेष रूप से, जिस स्मृति को इंगित कर रहा है) को हटाकर जादुई रूप से सूचक को '0' पर सेट नहीं किया जाता है। कंपाइलर को यह जानने का कोई तरीका नहीं है कि ऑब्जेक्ट के सभी पॉइंटर्स कहां हैं। –

+0

अगर मैं कई उत्तरों स्वीकार कर सकता हूं, तो मैं चाहता हूं। धन्यवाद – James

0

यदि ऑब्जेक्ट को हटाया जा रहा है, तो हटाया जा रहा है, यह एक स्पष्ट स्मृति त्रुटि है और अस्थिरता से कोई लेना देना नहीं है।

अस्थिरता का उद्देश्य संकलक को एक वैरिएबल के मान को "याद रखने" से रोकने के लिए है जो एक अलग थ्रेड द्वारा बदला जा सकता है, यानी संकलक को अनुकूलित करने से रोकें।

उदा। अपनी कक्षा एक सूचक सदस्य पी है और अपने विधि तक पहुँच रहा है, तो:

p->a; 
p->b; 

आदि और पी के भीतर "इस" इसलिए p->b की तुलना में यह था, जब यह p->a

किया एक अलग वस्तु तक पहुँचने हो सकता है अस्थिर है यदि पी को नष्ट कर दिया गया है, हालांकि "यह" हटा दिया गया था तो अस्थिर आपके बचाव में नहीं आएगा। संभवतः आपको लगता है कि यह "शून्य" होगा लेकिन यह नहीं होगा।

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

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