2014-07-17 2 views
5

क्या यह गारंटी है कि shared_ptr उसी समय पते पर रीसेट हो जाने पर समाप्त हो जाएगा?क्या यह गारंटी है कि shared_ptr उसी समय पते पर रीसेट हो जाने पर समाप्त हो जाएगा?

#include <cassert> 
#include <memory> 

int main() 
{ 
    int* i = new int(0); 
    std::shared_ptr<int> si(i); 
    std::weak_ptr<int> wi = si; 

    si.reset(i); 

    assert(wi.expired()); // wi.expired() == true (GCC 4.7) 
} 

या जब wi.expired() का मूल्य निर्धारित नहीं है यह मामला है?

संपादित करें:

मैं अब सवाल थोड़ा संशोधित:

यह गारंटी है कि weak_ptr समाप्त हो जाएगा जब shared_ptr एक ही पते, जो एक shared_ptr निहित जब यह weak_ptr प्रारंभ किया गया था पर रीसेट हो जाता है?

#include <cassert> 
#include <memory> 

int main() 
{ 
    int* i = new int(0); 
    std::shared_ptr<int> si(i); 
    std::weak_ptr<int> wi = si; 

    si.reset(); 

    int* j = new int(0); 
    // Suppose that new returns the same address that contains variable i : 
    assert(j == i); 

    si.reset(j); 

    assert(wi.expired()); // wi.expired() == true (GCC 4.7) 
} 
+1

संबंधित प्रश्न: [यदि मैं std :: shared_ptr को अपने आप रीसेट करता हूं तो क्या होता है] (http: // stackoverflow।com/प्रश्न/9785656/क्या-क्या होता है-अगर-ए-रीसेट एक stdshared-ptr करने वाली ही)। – ComicSansMS

उत्तर

11

एक तरफ, इसे वास्तव में करना चाहिए। दूसरी तरफ एक ही पॉइंटर को दो अलग-अलग साझा पॉइंटर्स (si-before-reset और si-after-reset) में असाइन करना सही नहीं है। वास्तव में, लागू si.reset(i) ऐसा होता है कि:

  • si के रेफरी गिनती करने के लिए 0
  • delete i फिर i को
  • पुनर्जन्म si अंक शुरू हो जाती है चला जाता है।

तो नव i सौंपा रीसेट के बाद इंगित करेगा स्मृति आवंटित करने के लिए नहीं है, और wi सही ढंग से समाप्त हो गई है (और एक segfault के मूल दे देंगे जब si चला गया है, अंत में, फिर i हटाने का प्रयास)।

अच्छा अभ्यास किसी साझा पॉइंटर को कभी साझा किए जाने के बाद नग्न पॉइंटर का संदर्भ नहीं देना है। संपादन के बाद

उत्तर:

ही वहां भी लागू होता है: तथ्य यह है कि सूचक ही है shared_ptr और इसके आंतरिक रेफरी-गिनती के साथ कोई संबंध नहीं है। यह शायद "बुराई" उदाहरण के साथ स्पष्ट है। यह गलत है:

int *i = new int; 

    std::shared_ptr<int> si1(i); 
    std::shared_ptr<int> si2(i); // deleting twice i on destruction of si2 - boom! 
    std::weak_ptr<int> wi1 = si1; 

    si1.reset(); 
    assert (wi1.expired());  // true 

यह आपका पहला उदाहरण के समान (वास्तव में एक ही) है: SI1 और SI2 हैं दो अलग shared_ptr के (वे si-पहले-रीसेट और सी-बाद-रीसेट थे)। तथ्य यह है कि si1 और si2 (गलत तरीके से) एक ही मेमोरी को इंगित करता है, साझा_प्टर के और उसके साथ कनेक्ट किए गए कमजोर_प्टर के जीवन से कोई लेना देना नहीं है।

i सूचक का पूर्ण मूल्य रेफ-गिनती निर्धारित करने के लिए उपयोग नहीं किया जाता है। दोनों साझा_प्टर और कमजोर_प्टर के लिए। तो हाँ, यह गारंटी है!

वास्तव में, जब आप अपने वर्ग के अंदर से एक वस्तु का shared_ptr की जरूरत है, आप enable_shared_from_this की जरूरत है - आप उपयोग कर रहे थे shared_from_this() के बजाय shared_ptr(this) आप अलग अलग shared_ptr का हर बार मिल रहे थे - उनमें से पहले जैसे ही अपने वस्तु को नष्ट करने रेफ-गिनती से बाहर चला गया था।

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

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