2011-03-04 7 views
5

मैं एक वर्ग Foo जिसके लिए मैं + ऑपरेटर अतिभारित किया है इस प्रकार है के साथ एक प्रतिलिपि रिटर्निंग:अतिभारित ऑपरेटरों

Foo Foo::operator+(const Bar &b) 
{ 
    Foo copy = (*this); 
    if (someCondition) return copy; 
    //snip 
} 
मेरे लिए

, इस उचित लग रहा है। हालांकि, जब भी मैं प्रतिलिपि वापस कर रहा हूं, विजुअल स्टूडियो मुझे एक त्रुटि का संकेत देता है जो 'ढेर के भ्रष्टाचार के कारण हो सकता है'। क्या मैंने जो किया है उसके साथ कुछ गड़बड़ है?

संपादित करें: अधिक जानकारी के साथ अद्यतन।

त्रुटि संदेश:

विंडोज sample.exe में एक ब्रेकपाइंट शुरू हो गया है।

यह ढेर का अपभ्रंश है, जो sample.exe या DLLs यह लोड हो जाने से किसी में एक बग को इंगित करता है की वजह से हो सकता है।

यह उपयोगकर्ता के कारण भी हो सकता है F12 दबाकर जबकि sample.exe में फ़ोकस है।

आउटपुट विंडो में नैदानिक ​​जानकारी हो सकती है।

प्रतिलिपि निर्माता:

Foo::Foo(const Foo&p) 
{ 
    some_pointer = p.get_some_pointer(); 
    some_value = p.get_some_value(); 
} 

कोड यह करने के लिए टूट जाता है:

//within dbgheap.c 
    extern "C" _CRTIMP int __cdecl _CrtIsValidHeapPointer(
      const void * pUserData 
      ) 
    { 
      if (!pUserData) 
       return FALSE; 

      if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), FALSE)) 
       return FALSE; 

      return HeapValidate(_crtheap, 0, pHdr(pUserData)); 
    } 
+4

क्या आप हमें 'फू' की कॉपी कन्स्ट्रक्टर दिखा सकते हैं? –

+1

त्रुटि का कोड क्या है? – metdos

+0

@ Space_C0wb0y @metdos मैंने अधिक जानकारी के साथ अपडेट किया है – socks

उत्तर

3

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

पहली चीज जो मैं करूँगा वह विनाशकों को देखता है और जांचता है कि आप उथले प्रतिलिपि और दोगुनी हटा नहीं रहे हैं। निम्न कोड के साथ उदाहरण के लिए:

// buggy!!! 
struct test { 
    int * data; 
    test() : data(new int[5]) {} 
    ~test() { delete [] data; } 
    test(test const & rhs) : data(rhs.data) {} 
    test& operator=(test const & rhs) { 
     data = rhs.data; 
    } 
}; 
int main() { 
    test t1;   // 5 ints allocated int t1.data 
    test t2(t1); // no memory allocated, t2.data == t1.data 
} // t2 out of scope: t2.~test() => delete t2.data 
    // t1 out of scope: t1.~test() => delete t1.data but both are the same: double delete 

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

हमेशा पॉइंटर्स के साथ, बाहरी प्रबंधन (पूर्व-निर्मित) कक्षाओं में संसाधन प्रबंधन को प्रतिनिधि करना बेहतर होता है। अद्वितीय स्वामित्व (और गहरी प्रतियां) के मामले में आपको शायद std::auto_ptr (या std::unique_ptr सी ++ 0x - या बूस्ट वेरिएंट) का उपयोग करना चाहिए। दूसरे मामले में, boost::shared_ptr (या std::shared_ptr सी ++ 0x में) का उपयोग करके यह सुनिश्चित होगा कि डेटा साझा किया जाता है और केवल एक बार हटा दिया जाता है।

+1

और यदि कक्षा ऑब्जेक्ट का मालिक नहीं है तो पॉइंटर पॉइंट्स, संदर्भ को प्राथमिकता दें। –

+1

@ स्पेस: एक वरीयता जो वर्ग को गैर-असाइन करने योग्य प्रभावी ढंग से प्रस्तुत करेगी (जो शायद अंकगणितीय ऑपरेटरों के साथ कक्षा के लिए अजीब होगी) ... – visitor

+0

@visitor: ठीक है, उस पर विचार नहीं किया। –