सी ++ चार सरणी [] स्मृति रिसाव [डुप्लिकेट]

Aug 18 2020

मैंने चार गिरफ्तारी बनाई [] और इसे स्ट्रिंग शाब्दिक आवंटित किया

char arr[] = "some string";                  // arr occupies 12 chars in memory
std::cout << std::strlen(arr)  << std::endl; // lenght is 11 chars + 1 null-terminator
                                             //arr[11] is '\0'

अगले मैं 6 तत्व में शून्य टर्मिनेटर डाल दिया

arr[5] = '\0';
std::cout << std::strlen(arr) << std::endl; // lenght is 5 chars  + 1 null-terminator
  1. क्या यह मेमोरी लीक है?
  2. कंपाइलर को कैसे पता चलेगा कि उसे पहले '0' के बाद मेमोरी खाली करनी होगी? (परिवर्तनशील गिरफ्तारी कब हटाएगा)
  3. क्या इस गिरते हुए वेरिएबल के लेन को बदलना और कंपाइलर को सूचित करना संभव है कि वेरिएबल को डिलीट करते समय इसे कितना फ्री करना चाहिए?

जवाब

5 user253751 Aug 18 2020 at 13:03
  1. क्या यह मेमोरी लीक है?

नहीं।

  1. कंपाइलर को कैसे पता चलेगा कि उसे पहले '0' के बाद मेमोरी खाली करनी होगी? (परिवर्तनशील गिरफ्तारी कब हटाएगा)

चर 12 वर्ण है। यह लेखन के समान है:

char arr[12] = "some string";

तो यह हमेशा 12 वर्णों को मुक्त करेगा। चर है 12 वर्ण की एक सरणी; तथ्य यह है कि 6 वां चर '\ 0' होता है पूरी तरह अप्रासंगिक है।

वैसे, एक बार जब आप 6 वें वर्ण को '\ 0' पर सेट करते हैं, तो आपको अभी भी सभी 12 वर्णों का उपयोग करने की अनुमति है, क्योंकि यह अभी भी 12-वर्ण की सरणी है। यहां तक ​​कि '0' के बाद वाले भी। लेकिन आप इसमें 13 चार्ट नहीं रख सकते।

  1. क्या इस गिरते हुए वेरिएबल के लेन को बदलना और कंपाइलर को सूचित करना संभव है कि वेरिएबल को डिलीट करते समय इसे कितना फ्री करना चाहिए?

नहीं। किसी भी चर का आकार बदलना संभव नहीं है।

6 cigien Aug 18 2020 at 13:03

इस कोड में:

char arr[] = "some string";

चर arrएक है स्थिर एक निश्चित आकार के साथ सरणी। यहां कोई डायनेमिक मेमोरी आवंटन नहीं है, और इसलिए मेमोरी लीक के बारे में चिंतित होने की आवश्यकता नहीं है। संकलक स्मृति का ध्यान रखेगा, चाहे आप जो भी लिखें arr

2 JoopEggen Aug 18 2020 at 13:07

संपूर्णता के लिए।

आवंटित मेमोरी में भी मेमोरी रिसाव नहीं है, जैसे कि:

char* arr = (char*) malloc(12);
strcpy(arr, "some string");
arr[6] = '\0';
free(arr);

स्मृति प्रबंधन आवंटित मेमोरी (12) द्वारा जाता है, अंतर्निहित उपयोग (नुल-टर्मिनेटेड चार *) द्वारा नहीं। (सी शैली, सी ++ इसी तरह)

1 Slava Aug 18 2020 at 13:56

लगता है कि आप इसे पिछड़ गए। C ++ में सरणी का आकार बदला नहीं जा सकता है, अवधि। उस तथ्य के कारण और क्योंकि तथ्य यह है कि यदि आप एक सूचक के रूप में सरणी पास करते हैं तो आप उस सरणी समझौते के वास्तविक आकार की ढीली जानकारी सी स्टाइल स्ट्रिंग्स के लिए बनाई गई थी - 0 बाइट उर्फ \0उर्फ नल टर्मिनेटर को स्ट्रिंग के गतिशील अंत के रूप में माना जाता है। समझौते का मतलब है कि सी स्टाइल स्ट्रिंग्स के साथ काम करने वाले कार्य इसे स्ट्रिंग समाप्ति के रूप में मानते हैं। यह आपको अलग-अलग लंबाई के तारों के लिए निश्चित आकार के सरणी का उपयोग करने और वास्तविक मेमोरी के आकार के बिना केवल एक पॉइंटर को पास करने के लिए इसे पढ़ने के लिए कार्यों के लिए अनुमति देता है (उदाहरण के लिए स्क्रीन पर प्रिंट करें)। ध्यान दें, जब आप चार सरणी को पास करते हैं, जो उस में डेटा लिखते हैं, तो आपको अक्सर यह बताने की आवश्यकता होती है कि वास्तविक सरणी आकार क्या है , ताकि फ़ंक्शन सीमा से बाहर स्मृति तक नहीं पहुंच सके क्योंकि यह फ़ंक्शन पहले से ही होने पर अशक्त टर्मिनेटर की उपेक्षा करेगा।

यही है, यह समझौता अलग-अलग परत पर होता है, जो एरे प्रबंधित है। तो जो भी डेटा आप उस एरे में डालते हैं, वह भाषा के दृष्टिकोण से उसके आकार को प्रभावित नहीं करेगा, C ++ कंपाइलर के लिए आपने निश्चित आकार की ऐरे बनाई जिसमें आप कुछ डेटा डालते हैं और जब यह आजीवन आ जाता है तो कंपाइलर इसे पूरे निश्चित आकार के एरे के रूप में नष्ट कर देता है। इससे कोई फर्क नहीं पड़ता कि आपने वहां जीरो बाइट लगाई या नहीं।

VladfromMoscow Aug 18 2020 at 13:16

एक मेमोरी रिसाव तब होता है जब प्रोग्रामर द्वारा ऑपरेटर का उपयोग करके एक मेमोरी आवंटित की जाती newथी और ऑपरेटर deleteया का उपयोग करके हटाया नहीं गया था delete []

इस घोषणा में

char arr[] = "some string"; 

यह संकलक (या सिस्टम) अक्षर सरणी के लिए स्मृति को आवंटित किया गया है जिसमें स्वचालित भंडारण अवधि या स्थिर भंडारण अवधि है। तो संकलक (या सिस्टम) आवंटित मेमोरी को मुक्त करने के लिए जिम्मेदार हैं। आवंटित मेमोरी का पता कंपाइलर (या सिस्टम) को पता होता है।

इस कथन का उपयोग करना

arr[5] = '\0';

आपने सरणी को पुनः प्राप्त नहीं किया। आपने केवल इसकी सामग्री को केवल एक बाइट में ही बदल दिया है।

कंपाइलर को कैसे पता चलेगा कि उसे पहले '0' के बाद मेमोरी खाली करनी होगी? (परिवर्तनशील गिरफ्तारी कब हटाएगा)

क्योंकि कंपाइलर (या सिस्टम) जानता है कि एरे टाइप का ऑब्जेक्ट कैसे घोषित किया गया था।

ऑब्जेक्ट के लिए 12 बाइट्स आवंटित की गई थी।

char arr[] = "some string"; 

क्या इस गिरते हुए वेरिएबल के लेन को बदलना और कंपाइलर को सूचित करना संभव है कि वेरिएबल को डिलीट करते समय इसे कितना फ्री करना चाहिए?

मुझे लगता है कि आपको वस्तु के आकार से मतलब है। नहीं, आप ऑब्जेक्ट का आकार नहीं बदल सकते क्योंकि यह आप नहीं थे, जिन्होंने ऑब्जेक्ट के लिए मेमोरी आवंटित की थी।

यदि आप ऑपरेटर newको उदाहरण के लिए आवंटित करने के लिए उपयोग करते हैं, तो आप उस वस्तु को पुनः प्राप्त कर सकते हैं

char *arr = new char[12];

std::strcpy( arr, "some string" );

//...

char *tmp = new char[20];

strcpy( tmp, "another " );
strcat( tmp, arr );

delete [] arr;
arr = tmp;