अगर मैं आबंटित स्मृति के बीच में रहना एक '\ 0', करता
(क।) मुक्त() अभी भी ठीक से काम, और
हां।
(बी।) '\ 0' अपरिवर्तनीय होने के बाद की जगह करता है? एक बार '\ 0' जोड़ा जाता है, क्या स्मृति बस वापस आती है, या क्या यह वहां तक घूमने वाली जगह है जहां तक मुक्त() कहा जाता है?
निर्भर करता है। अक्सर, जब आप बड़ी मात्रा में हीप स्पेस आवंटित करते हैं, तो सिस्टम पहले वर्चुअल एड्रेस स्पेस आवंटित करता है - जैसा कि आप पृष्ठों पर लिखते हैं, कुछ वास्तविक भौतिक स्मृति इसे वापस करने के लिए असाइन की जाती है (और बाद में जब आपके ओएस में वर्चुअल मेमोरी हो तो डिस्क पर बदल जाता है समर्थन)। प्रसिद्ध रूप से, वर्चुअल एड्रेस स्पेस और वास्तविक भौतिक/स्वैप मेमोरी के अपर्याप्त आवंटन के बीच यह अंतर स्पैस एरे को ऐसे ओएस पर उचित मेमोरी कुशल होने की अनुमति देता है।
अब, इस वर्चुअल एड्रेसिंग और पेजिंग की ग्रैन्युलरिटी मेमोरी पेज आकार में है - जो 4k, 8k, 16k ... हो सकती है? अधिकांश ओएस में एक फ़ंक्शन होता है जिसे आप पेज आकार का पता लगाने के लिए कॉल कर सकते हैं। इसलिए, यदि आप बहुत छोटे आवंटन कर रहे हैं तो पेज आकार तक गोल करना अपर्याप्त है, और यदि आपके पास वास्तव में उपयोग की जाने वाली मेमोरी की मात्रा के सापेक्ष एक सीमित पता स्थान है तो ऊपर वर्णित तरीके से वर्चुअल एड्रेसिंग के आधार पर स्केल नहीं करेगा (उदाहरण के लिए, 32-बिट एड्रेसिंग के साथ 4 जीबी रैम)। दूसरी तरफ, यदि आपके पास 32 जीबी रैम के साथ 64-बिट प्रक्रिया चल रही है, और अपेक्षाकृत कुछ ऐसे स्ट्रिंग आवंटन कर रही हैं, तो आपके पास खेलने के लिए वर्चुअल एड्रेस स्पेस की एक बड़ी मात्रा है और पृष्ठ आकार तक गोल करने के लिए ' टी राशि ज्यादा है।
लेकिन - पूरे बफर में लिखने के बीच अंतर को ध्यान में रखें, फिर इसे पहले के बिंदु पर समाप्त कर दें (जिस स्थिति में एक बार लिखित स्मृति में स्मृति का समर्थन होगा और स्वैप में समाप्त हो सकता है) जिसमें एक बड़ा बफर बनाम बना हुआ है आप केवल पहले बिट को लिखते हैं, फिर समाप्त करें (जिस स्थिति में बैकिंग मेमोरी केवल पृष्ठ आकार के लिए उपयोग की गई उपयोग की गई जगह के लिए आवंटित की जाती है)।
यह भी उनका कहना है कि कई ऑपरेटिंग सिस्टम स्मृति ढेर पर ऑपरेटिंग सिस्टम को वापस नहीं किया जा सकता है जब तक प्रक्रिया समाप्त हो जाता है लायक है: बजाय, malloc/मुक्त पुस्तकालय ओएस जब यह ढेर बढ़ने की जरूरत है सूचित करता है (उदाहरण के लिए sbrk()
का उपयोग कर विंडोज पर यूनिक्स या VirtualAlloc()
पर)। उस अर्थ में, free()
मेमोरी आपकी प्रक्रिया के पुन: उपयोग के लिए स्वतंत्र है, लेकिन अन्य प्रक्रियाओं के उपयोग के लिए स्वतंत्र नहीं है। कुछ ऑपरेटिंग सिस्टम इसे अनुकूलित करते हैं - उदाहरण के लिए, बहुत बड़े आवंटन के लिए एक विशिष्ट और स्वतंत्र रूप से रिलीज मेमोरी क्षेत्र का उपयोग करना।
क्या यह आम तौर पर खराब प्रोग्रामिंग शैली है जो इस लटकती जगह को छोड़ने के लिए है, ताकि कुछ आगे प्रोग्रामिंग समय को मॉलोक को कॉल करने से पहले आवश्यक स्थान की गणना कर सकें?
फिर से, यह इस बात पर निर्भर करता है कि आप कितने आवंटन कर रहे हैं। अपने आभासी पता स्थान/रैम के लिए एक महान कई रिश्तेदार नहीं हैं, तो - आप स्पष्ट रूप से स्मृति पुस्तकालय सभी मूल रूप से अनुरोधित स्मृति वास्तव में realloc()
का उपयोग कर की जरूरत है नहीं बताना चाहते हैं, या आप और भी अधिक सशक्त आधारित strdup()
इस्तेमाल कर सकते हैं और एक नए ब्लॉक आवंटित करने के लिए वास्तविक जरूरतों पर (तब free()
मूल) - अपने malloc/मुक्त पुस्तकालय क्रियान्वयन के आधार पर बाहर बेहतर या बदतर काम हो सकता है कि है, लेकिन बहुत कुछ अनुप्रयोगों में काफी कोई अंतर से प्रभावित होंगे।
कभी-कभी आपका कोड लाइब्रेरी में हो सकता है जहां आप अनुमान लगा सकते हैं कि कॉलिंग एप्लिकेशन कितने स्ट्रिंग उदाहरण प्रबंधित करेगा - ऐसे मामलों में धीमे व्यवहार को प्रदान करना बेहतर होता है जो कभी भी बुरा नहीं होता ... इसलिए सिकुड़ने की ओर झुकना स्मृति ब्लॉक बल्कि (मूल स्ट्रिंग बफर बर्बाद की एक अज्ञात अनुपात एक रोग के मामले में की तुलना में (अतिरिक्त संचालन की एक निर्धारित संख्या इतनी बड़ी-ओ दक्षता प्रभावित नहीं करता है) स्ट्रिंग डेटा फिट करने के लिए - शून्य या एक चरित्र मनमाने ढंग से इस्तेमाल किया के बाद बड़े आवंटन)। एक प्रदर्शन अनुकूलन के रूप में यदि आप असामान्य स्थान> = उपयोग की गई जगह - स्वाद के लिए धुन, या इसे कॉलर-कॉन्फ़िगर करने योग्य बनाते हैं तो आप केवल लौटने वाली स्मृति को परेशान कर सकते हैं।
आप किसी अन्य जवाब पर टिप्पणी:
तो यह पहचानने के लिए कि क्या realloc अधिक समय लगेगा, या preprocessing आकार निर्धारण करने के लिए नीचे आता है?
यदि प्रदर्शन आपकी सर्वोच्च प्राथमिकता है, तो हाँ - आप प्रोफाइल करना चाहते हैं। आप सीपीयू बाध्य नहीं हैं, तो एक सामान्य नियम के रूप में लेते हैं "preprocessing" मारा और एक सही आकार आवंटन करते हैं - वहाँ सिर्फ कम विखंडन और गड़बड़ है। काउंटरिंग, अगर आपको कुछ फ़ंक्शन के लिए एक विशेष प्रीप्रोकैसिंग मोड लिखना है - यह त्रुटियों और कोड को बनाए रखने के लिए अतिरिक्त "सतह" है। (यह व्यापार बंद निर्णय आमतौर पर की जरूरत है जब snprintf()
से अपने खुद के asprintf()
को लागू करने के लिए, लेकिन वहाँ कम से कम आप snprintf()
कार्य करने के लिए भरोसा कर सकते हैं के रूप में दस्तावेज और व्यक्तिगत रूप से इसे बनाए रखने की जरूरत नहीं है)।
ध्यान दें कि यह बुरा शैली पूछने के लिए कि कॉल करने का उपयोग 'मुक्त()' पुनःआवंटन वस्तुओं, कार्यों से लौटे रूप में फोन करने वाले एक अलग सी पुस्तकालय के खिलाफ जोड़ा जा सकता है है, और यह भी एक अलग का उपयोग करने से बंद हो जाता है भविष्य में आवंटक। आपको अपनी लाइब्रेरी से लौटाई गई तारों को मुक्त करने के लिए एक छोटा रैपर फ़ंक्शन प्रदान करना चाहिए। –
टिप के लिए धन्यवाद, लेकिन मुझे यकीन नहीं है कि रैपर कहलाएगा: प्रोग्राम से बाहर निकलने पर स्वचालित रूप से? मुझे यकीन नहीं है कि मैं इसे कैसे कार्यान्वित कर सकता हूं .. यदि यह मेरे फ़ंक्शन के लिए सिर्फ एक रैपर है, तो मैं अपने उपयोगकर्ता को ऑपरेशन (मेरे आउटपुट स्ट्रिंग पर) कैसे टाइप करूं, यह मानते हुए कि वह मुफ्त में करने से पहले कुछ करना चाहती है? क्या यह अधिक पारंपरिक है और शून्य कार्यों को लिखने के लिए स्वीकार किया गया है जो एक आउटपुट पॉइंटर का अनुरोध करते हैं जिसे मैं संशोधित करने के लिए स्वतंत्र हूं? अगर मुझे ऐसे सूचक की लंबाई को फिर से बदलने या बदलने की ज़रूरत है तो क्या होगा? (एक तरफ: मुझे std :: string के बजाय char * या const char * का उपयोग करना होगा) – Cindeselia
रुको, बस यह देखा: ऐसा लगता है कि एक कॉन्स char वापस लौटने की तरह * इस खराब शैली बिंदु को हल कर सकता है? http://stackoverflow.com/questions/3323675/c-fastest-method-to-return-a-c-string – Cindeselia