2010-11-27 6 views
5

मुझे ऑपरेटर नया काम मिल गया है, लेकिन जैसे ही मैं डिलीट करता हूं, यह free (ptr) लाइन पर दुर्घटनाग्रस्त हो जाता है। क्या कोई यह बता सकता है कि ऑपरेटर को ओवरलोड करने और इस बेस क्लास में हटाए जाने पर मैं क्या गलत कर रहा हूं? संकेत: मैं डिजाइन मुद्दों के बारे में नहीं पूछ रहा हूं।ऑपरेटर हीप भ्रष्टाचार का कारण बनता है जबकि ऑपरेटर नया काम कर रहा है

class Base { 
private: 
    int i; 

public: 
    Base() : i (10) { 
    } 

    static void * operator new (size_t size) { 
     if (size = 0) size = 1; // please read this line carefully! size = 0! 
     return malloc (size); 
    } 

    static void operator delete (void *ptr, size_t size) { 
     if (ptr == NULL) return; 
     free (ptr); 
    } 
}; 
+1

आप दो बार एक वस्तु हटा सकते हैं या एक सूचक के माध्यम से एक वस्तु 'new' बुला से प्राप्त नहीं हटाने का प्रयास कर रहे हैं? –

+0

एक साइड नोट के रूप में, 'मुफ़्त (एनयूएलएल) 'सुरक्षित होने की गारंटी है (एक नो-ऑप), इसलिए आपको विशेष मामले की आवश्यकता नहीं है। –

+0

एचएम ... मेरा बुरा: यदि आप 'if (size = 0 0)' 'if (size = 0) 'के साथ' if (size == 0)' को प्रतिस्थापित करते हैं और एक निजी डेटा सदस्य के साथ-साथ एक कन्स्ट्रक्टर भी जोड़ते हैं, तो कोड विफल हो जाएगा। मुझे पता है कि 'आकार = 0' एक बग है जो नहीं होना चाहिए, लेकिन जब आप कन्स्ट्रक्टर में इस वर्ग के निजी डेटा सदस्य को प्रारंभ करते हैं तो कोड केवल तभी विफल होता है। – Jaywalker

उत्तर

4

यह मेरे लिए काम करता है:

#include <cstdlib> 
using namespace std; 
class Base { 
public: 
    void * operator new(size_t size) { 
     if (size == 0) size = 1; 
     return malloc (size); 
    } 

    void operator delete (void *ptr, size_t size) { 
     if (ptr == NULL) return; 
     free (ptr); 
    } 
}; 

int main() 
{ 
    Base* b = new Base; 
    delete b; 
    return 0; 
} 

[email protected]:/tmp$ g++ -o test test.cpp 
[email protected]:/tmp$ ./test 
[email protected]:/tmp$ valgrind ./test 
==7229== HEAP SUMMARY: 
==7229==  in use at exit: 0 bytes in 0 blocks 
==7229== total heap usage: 1 allocs, 1 frees, 1 bytes allocated 
==7229== 
==7229== All heap blocks were freed -- no leaks are possible 
==7229== 
==7229== For counts of detected and suppressed errors, rerun with: -v 
==7229== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4) 
+0

धन्यवाद। हाँ, आपका कोड ठीक है। मैंने अपने कोड में कुछ और बदलाव किए हैं। क्या आप उस पर टिप्पणी कर सकते हैं? – Jaywalker

1

मैं नमूना कोड आप दे दिया है के साथ किसी भी समस्या नहीं दिख रहा।

निम्नलिखित मेरे लिए ठीक काम करता है।

[email protected] ~ $ cat leak_check.cpp && g++ leak_check.cpp && valgrind --leak-check=full ./a.out 
#include <cstdlib> 
class Base { 
public: 
    static void * operator new (size_t size) { 
     if (size == 0) size = 1; 
     return malloc (size); 
    } 

    static void operator delete (void *ptr, size_t size) { 
     if (ptr == NULL) return; 
     free (ptr); 
    } 
}; 

int main() 
{ 
    Base * p = (Base *) Base::operator new(sizeof(Base)); 
    Base::operator delete((void*)p,sizeof(Base)); 
} 
==4561== Memcheck, a memory error detector 
==4561== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. 
==4561== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info 
==4561== Command: ./a.out 
==4561== 
==4561== 
==4561== HEAP SUMMARY: 
==4561==  in use at exit: 0 bytes in 0 blocks 
==4561== total heap usage: 1 allocs, 1 frees, 1 bytes allocated 
==4561== 
==4561== All heap blocks were freed -- no leaks are possible 
==4561== 
==4561== For counts of detected and suppressed errors, rerun with: -v 
==4561== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 6) 

बीटीडब्ल्यू एक शून्य सूचक को मुक्त करना बिल्कुल ठीक है।

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

तो if (ptr == NULL) return; छोड़ा जा सकता है।

2

वास्तविक समस्या न तो new और न ही delete ऑपरेटरों के साथ है। उनका कार्यान्वयन बहुत सरल है, यहां कोई समस्या नहीं है।

आपके पास ढेर भ्रष्टाचार जैसी वास्तविक समस्या है। यह आपके कोड के कारण होता है, जरूरी नहीं कि कोड Base ऑब्जेक्ट्स का उपयोग करता है। यह केवल तब ही ढेर भ्रष्टाचार की खोज हो जाती है जब आप delete अपनी ऑब्जेक्ट करते हैं।

शायद आपके पास कुछ कोड है जो आपके ऑब्जेक्ट delete से पहले ही भ्रष्टाचार ढेर करता है।

आपको अमान्य स्मृति पहुंच के लिए अपना कोड देखना चाहिए। इसमें शामिल हैं:

  1. आप और अधिक स्मृति आवंटित की तुलना में
  2. सुनिश्चित करें कि आप स्मृति का उपयोग नहीं करते आप इसे मुक्त कर के बाद का उपयोग नहीं है सुनिश्चित करना।
  3. आदि