2009-04-18 25 views
20

हटा रहा है यह प्रश्न this one से संबंधित है।एक चार सरणी

char *p = new char[200]; 
delete[] p; 

अगर आप पी को हटाने से पहले p[100] = '\0' सेट क्या होगा: इस कोड को देखते हुए?

मेरे पास कुछ कोड था जहां मुझे एक डीबग त्रुटि मिली, जब मैंने नल-टर्मिनेटेड चार सरणी को हटाने की कोशिश की, तो ढेर मेमोरी को हटाने के बारे में कुछ। यह सरणी की सीमाओं से स्मृति को हटाना प्रतीत होता था।

उत्तर

38

कोड:

char *p = new char[200]; 
p[100] = '\0'; 
delete[] p; 

पूरी तरह से वैध सी ++ है। हटाएं नल-टर्मिनेटेड तारों के बारे में नहीं जानते या उनकी परवाह नहीं करते हैं, इसलिए आपकी त्रुटि का कोई अन्य कारण होना चाहिए।

+0

_ "हटाएं नापसंद के बारे में पता नहीं है या परवाह नहीं है ..." _ यह सच नहीं है। यदि आपके पास 'p [2]' है, तो आप गलती से 'p [2] =' \ 0'' 'सेट करते हैं,' p' को हटाने से स्मृति-संबंधित त्रुटि मिल जाएगी, जाहिर है क्योंकि पी [2] पर मेमोरी को हटाना है का प्रयास किया। – user3140280

+0

यह सच है। मेरे पास एक ही परिदृश्य के लिए एक ढेर भ्रष्टाचार था। मेरे पास आकार 10 की एक सरणी थी। मैंने गलती से सरणी [10] = '\ 0' सेट की है और जब मैं [] सरणी हटाता हूं, तो मुझे भ्रष्टाचार में भ्रष्टाचार की त्रुटि मिलती है। इसे ठीक किया और यह चला गया। कुछ नया सीख लिया। – Nazeeh

+10

@Nazeeh आपने यहां कुछ गलत सीखा होगा या आपने जो कुछ समझ लिया है उसे बिल्कुल उद्धृत नहीं किया हो सकता है। आकार 10 की एक सरणी में, 10 वीं तत्व 9वीं इंडेक्स पर है, 10 नहीं, अगर आप 10 वीं इंडेक्स पर कुछ भी लिखते हैं और लिखते हैं, तो आपने पहले से ही ढेर दूषित कर दिया है, आपके ऐप को क्रैश करने के लिए डिलीट करना अप्रासंगिक है, आपका ऐप क्रैश करने के लिए बाध्य है वैसे भी, यह सिर्फ समय की बात है। आपकी गलती के ठीक बाद कॉलिंग को हटाएं बस आप भाग्यशाली हैं कि आपको जल्द ही गलती (और एक सरल उपयोग मामले में) देखने की आवश्यकता है, फिर इस त्रुटि को खोजने के लिए एक गन्दा विवरण से गुजरना है। – user734028

3

इससे कोई फर्क नहीं पड़ता। हटाएं [] को इसकी सामग्री के बावजूद गतिशील आवंटित सरणी को हटाने के लिए उपयोग किया जाना चाहिए।

8

कुछ खास नहीं होगा। आप आवंटित स्मृति के बीच में कुछ जगह पर लिखेंगे (प्रारंभ से अलग 100 बाइट, आवंटित स्मृति के अंत से पहले 99 बाइट्स)।

फिर आप आवंटित स्मृति को मुक्त कर देंगे। संकलक इसे ठीक तरह से संभाल लेंगे जैसा हम उम्मीद करेंगे। इसके द्वारा आवंटित स्मृति शून्य समाप्त तारों से पूरी तरह से असंबंधित है। आप उस स्मृति में जो कुछ भी चाहते हैं उसे छू सकते हैं। यह भंडारण का कुछ "कच्चा" हिस्सा है, आप उस स्मृति में कुछ मनमानी सी ++ ऑब्जेक्ट भी बना सकते हैं (प्लेसमेंट नया)।

आपकी बग कहीं और है। उदाहरण के लिए, कुछ सामान्य त्रुटि यह एक है, जहां निर्माता एक बार कहा जाता है डबल को हटाने कुछ है, लेकिन नाशक दो बार कहा जाता है,:

struct A { P *p; A() { p = new P; } ~A() { delete p; } }; 
A getA() { return A(); } int main() { A a = getA(); } 

अब, क्या होता है कि डिफ़ॉल्ट निर्माता एक बार कहा जाता है, और है बनाई गई वस्तु को शून्य या अधिक बार कॉपी किया गया है। लेकिन विनाशक बनाई गई प्रत्येक प्रतिलिपि के लिए चलाया जाता है। इस प्रकार, आप पॉइंटर पर एक से अधिक बार विनाशक को बुलाएंगे, जिससे ऐसी अजीब चीजें होती हैं। को ठीक करने का सही तरीका एक स्मार्ट पॉइंटर का उपयोग करना है, जैसे shared_ptr। एक अभ्यास के रूप में, आप बिना उचित कॉपी कन्स्ट्रक्टर लिखकर, बिना ऑब्जेक्ट की प्रतिलिपि बना सकते हैं और कॉपी कन्स्ट्रक्टर में मेमोरी आवंटित कर सकते हैं, ताकि प्रतिलिपि और संबंधित मूल वस्तु अलग-अलग पॉइंटर्स रख सके।

1

यह ठीक काम करना चाहिए, जहां तक ​​मैं कह सकता हूं। आप स्मृति का एक हिस्सा आवंटित करते हैं, और ओएस को इसका ट्रैक रखना चाहिए, और पूछे जाने पर इसे रद्द करने में सक्षम होना चाहिए। इससे कोई फर्क नहीं पड़ता कि आपने आवंटित बफर में क्या मूल्य डाले हैं।

एक वर्ण सरणी के बीच में एक नल चिपकाना निश्चित रूप से सी स्ट्रिंग फ़ंक्शंस जैसे strcmp, strlen इत्यादि में हस्तक्षेप करेगा, लेकिन यह पूरी तरह से एक और मामला है।

6

मुझे लगता है कि आप एक सीएल स्टाइल स्ट्रिंग का प्रतिनिधित्व करने वाले चार सरणी के साथ एक सादे पुराने चार सरणी को भ्रमित कर रहे हैं। सी ++ डिलीट ऑपरेटर सी शैली स्ट्रिंग सरणी के लिए कुछ भी परवाह नहीं करता है। यह सब कभी देखेगा वर्णों की एक सरणी है। यह वास्तव में int की सरणी हटाने से अलग नहीं है।

शून्य टर्मिनेटर की उपस्थिति या अनुपस्थिति केवल उन कार्यों में प्रासंगिक है जो char* को सी शैली स्ट्रिंग के रूप में मानती हैं।

0

जैसा कि अन्य ने ध्यान दिया है, आपके द्वारा पोस्ट किया गया कोड पूरी तरह से मान्य है और किसी भी समस्या का कारण नहीं बनना चाहिए।

त्रुटि p के बीच में कहीं भी बदलकर हो सकती है।

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