2008-11-04 17 views
12

साथ auto_ptr उपयोग करने के लिए अगर मैं का उपयोग करयह गलत नया चार [n]

std::auto_ptr<char> buffer(new char[n]); 

तो बफर स्वचालित रूप से बफर क्षेत्र से बाहर चला जाता है हटा दिया गया है एक अस्थायी ऑटो नष्ट कर दिया चरित्र बफर की घोषणा है। मुझे लगता है कि बफर हटाकर हटा दिया गया है।

हालांकि बफर को नए [] का उपयोग करके बनाया गया था, और इसलिए कड़ाई से बोलने वाले बफर को हटाकर हटाया जाना चाहिए []।

क्या यह संभावना है कि इस विसंगति से स्मृति रिसाव हो सकता है?

उत्तर

19

नए [] undefined के साथ आवंटित सूचक पर हटाने का व्यवहार। जैसा कि आपने माना है, स्मार्ट पॉइंटर गुंजाइश से बाहर हो जाता है, auto_ptr does call delete। यह केवल स्मृति रिसाव नहीं है जिसके बारे में आपको चिंता करना है - क्रैश और अन्य अजीब व्यवहार संभव हैं।

यदि आपको सूचक के स्वामित्व को स्थानांतरित करने की आवश्यकता नहीं है, तो बूस्ट की scoped_array कक्षा वह हो सकती है जो आप खोज रहे हैं।

7

जो अपरिभाषित व्यवहार उत्पन्न करता है (उदाहरण के लिए मेमोरी रिसाव से भी बदतर हो सकता है, उदाहरण के लिए भ्रष्टाचार ढेर) boost's scoped_array or shared_array इसके बजाय प्रयास करें।

6

नए [] के साथ आवंटित डेटा पर कॉलिंग डिलीट अपरिभाषित है। इसका मतलब है कि संकलक कोड उत्पन्न कर सकता है जो कुछ भी कर सकता है। हालांकि इस मामले में यह शायद काम करता है क्योंकि सरणी में अलग-अलग वर्णों को नष्ट करने की आवश्यकता नहीं है, केवल सरणी ही।

अभी भी इस व्यवहार को अपरिभाषित होने के बाद से, मैं दृढ़ता से std::vector<char> या boost::scoped_array<char>/boost::shared_array<char> का उपयोग करने की अनुशंसा करता हूं। इस मामले में std::auto_ptr<> का उपयोग करने के लिए सभी पूरी तरह व्यवहार्य और बेहतर विकल्प हैं। यदि आप std::vector का उपयोग करते हैं तो आपके पास आवश्यक होने पर बफर को गतिशील रूप से बढ़ने की संभावना भी है।

10

मैं चार के बफर के रूप में वेक्टर का उपयोग करता हूं।

std::vector<char> buffer(size); 

read(input,&buffer[0],size); 

मूल रूप से यदि आप की आवश्यकता नहीं है तो आप भी नए कॉल नहीं करना चाहते हैं।
एक वेक्टर एक रन-टाइम आकार का बफर प्रदान करता है जिसे आप एक सरणी (बफर) की तरह उपयोग कर सकते हैं।

सबसे अच्छा हिस्सा यह है कि वेक्टर स्वयं के बाद साफ हो जाता है और मानक गारंटी देता है कि वेक्टर में सभी तत्व विरोधाभासी भंडारण में होंगे। एक बफर के लिए बिल्कुल सही।

या अधिक गारंटी formaly है:

(&buffer[0]) + size == (&buffer[size]) 
5

इसका कोई खास कारण std :: स्ट्रिंग का उपयोग करना नहीं है? std :: वेक्टर, जैसा कि अन्य ने सुझाव दिया है? आप जो कर रहे हैं वह गलत है, लेकिन यह जानने के बिना कि आप किसी और चीज की सिफारिश करने की कोशिश कर रहे हैं, मुश्किल है।

0

यह एक बहुत ही सरल समाधान के लिए भयानक जटिल लगता है।

char *c=new char[n] 

का उपयोग करके आपके साथ क्या गलत है, और फिर इसे हटा रहा है? या, यदि आप थोड़ा और अधिक गतिशील समाधान की जरूरत है,

vector<char> c 

Occam के रेजर, यार।:-)

+1

बिंदु हटाए जाने की गारंटी के लिए है के साथ। एक स्मार्ट पॉइंटर/सरणी का उपयोग करना सामान्य प्रोग्रामिंग गुंडों के साथ सुरक्षित है और अपवाद होने पर स्मृति को मुक्त करने के लिए पर्याप्त स्मार्ट होने के नाते भी सुरक्षित है। सी सरणी का उपयोग सीधे मेमोरी रिसाव के लिए पूछ रहा है। – Diastrophism

+1

पूरा बिंदु यह है कि हम हटाना की गारंटी देना चाहते हैं। इस प्रकार अनचाहे रॉ नया एक अच्छा जवाब नहीं है। दूसरी ओर std :: वेक्टर एक अच्छा जवाब है –

4

हां, यह गलत है। एक छोटे से रैपर के साथ लपेटें।

typedef< typename T_ > 
struct auto_vec{ 
    T_* t_; 
    auto_vec(T_* t): t_(t) {} 
    ~auto_vec() { delete[] t_; } 
    T_* get() const { return t_; } 
    T_* operator->() const { return get(); } 
    T_& operator*() const { return *get(); } 
    /* you should also define operator=, reset and release, if you plan to use them */ 
} 

auto_vec<char> buffer(new char[n]); 
2

प्रश्न पूछने के बाद से कुछ साल बीत चुके हैं।

लेकिन मैं एक खोज से यह पेज मारा, तो मैं सोचा मैं भी ध्यान दें सकता है: std :: unique_ptr, auto_ptr के लिए सी ++ 11 प्रतिस्थापन, के साथ नए [] बनाया वस्तुओं का विलोपन संभाल कर सकते हैं।

std :: unique_ptr के दो संस्करण हैं: 1) का प्रबंध के जीवनकाल एक वस्तु (जैसे नए के साथ आवंटित) 2) वस्तुओं की एक डायनामिक रूप से आवंटित सरणी के जीवनकाल (जैसे आवंटित प्रबंध []) नई

cppreference unique_ptr

+0

यह "एमएसडीएन" के लिए विशिष्ट नहीं होगा (सीएल उस कंपाइलर का नाम है, हालांकि।) –

+0

पर्याप्त मेला। माइक्रोसॉफ्ट-एसटीएल विशिष्ट के बजाय सामान्य सी ++ होने के संदर्भ को अद्यतन किया गया। अन्य उत्तरों 2008 में ठीक थे जब पहली बार पूछा गया था, लेकिन अब ऑटो_प्टर लंबे समय से बहिष्कृत है, मुझे उम्मीद है कि कोई भी नौसिखिया वेब सर्फर इस पृष्ठ को हिट नहीं करेगा और सोचता है कि उन्हें बूस्ट या अपने स्वयं के रैपर या किसी और चीज की आवश्यकता है जब अच्छा समाधान एसटीएल में मुफ्त में है अभी व। – Daryn

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