C में `free` बाइट की संख्या को मुक्त करने के लिए क्यों नहीं लेता है?


84

बस स्पष्ट होने के लिए: मुझे पता है कि mallocऔर freeसी लाइब्रेरी में कार्यान्वित किए जाते हैं, जो आमतौर पर ओएस से मेमोरी का हिस्सा आवंटित करते हैं और अपने स्वयं के प्रबंधन को आवेदन के लिए बहुत सारी मेमोरी को पार्सल करते हैं और आवंटित बाइट्स की संख्या का ट्रैक रखते हैं। । यह सवाल यह नहीं है कि मुक्त कैसे जानता है कि मुक्त करने के लिए कितना है

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

तो, संक्षेप में, क्यों mallocऔर freeऐसे बनाए गए थे कि उन्हें आंतरिक रूप से आवंटित बाइट्स की संख्या का ट्रैक रखना आवश्यक है? क्या यह सिर्फ एक ऐतिहासिक दुर्घटना है?

एक छोटा-सा संपादन: कुछ लोगों ने "क्या होगा अगर आपने आवंटित की तुलना में एक अलग राशि मुक्त किया है" जैसे बिंदु प्रदान किए हैं। मेरी कल्पना की गई एपीआई को बस आवंटित बाइट्स की संख्या को मुक्त करने के लिए एक की आवश्यकता हो सकती है; अधिक या कम मुक्त बस यूबी या कार्यान्वयन को परिभाषित किया जा सकता है। मैं अन्य संभावनाओं के बारे में चर्चा को हतोत्साहित नहीं करना चाहता।


18
क्योंकि यह पहले से ही आवंटन का ट्रैक रखने के लिए एक दर्द है, और यह कोड को और अधिक जटिल करेगा यदि आपको इसके अलावा आकार का ट्रैक रखना है।
जेन्स गुस्तेद

11
मैं कई कारणों के बारे में सोच सकता हूं: यदि उन्हें नहीं करना है तो उपयोगकर्ता इसे क्यों बनाते हैं? यदि उपयोगकर्ता इसे गड़बड़ करता है तो क्या होगा? यह वैसे भी एक बेमानी सवाल है। यदि वे दूसरी पसंद करते हैं, तो आप अभी भी पूछ रहे हैं कि क्यों।
BoBTFish

15
@BoBTFish: यह वह सी है जिसके बारे में हम बात कर रहे हैं, न कि पायथन या सी ++। उपयोगकर्ता को पहले से ही $ ज करना पड़ता है! 1 टन उसे नहीं करना पड़ता है। वह कारण नहीं है।
user541686

4
K & R को इस बारे में कुछ नहीं कहना है। हम उन सभी को अनुमान लगा सकते हैं जो हमें पसंद हैं, लेकिन मुझे लगता है कि मूल कारण इतिहास में खो सकता है ।
BoBTFish

35
आपको प्रोग्रामर को ब्लॉक के आकार में सही तरीके से पास करने की आवश्यकता नहीं है, क्योंकि कॉल करने वाले mallocको ब्लॉक के आकार का पता नहीं होता हैmallocअक्सर एक ऐसा ब्लॉक देता है जो अनुरोध से बड़ा है। सबसे अच्छा, प्रोग्रामर malloc()कॉल में अनुरोध किए गए आकार में पास हो सकता है , जो बिल्कुल भी कार्यान्वयनकर्ता की मदद नहीं करेगा free()
बेन वोइगट

जवाबों:


97

एक-तर्क free(void *)(यूनिक्स V7 में पेश किया गया) का पहले के दो-तर्क पर एक और बड़ा फायदा है mfree(void *, size_t)जो मैंने यहां नहीं देखा है: एक तर्क freeनाटकीय रूप से हर दूसरे एपीआई को सरल करता है जो ढेर मेमोरी के साथ काम करता है। उदाहरण के लिए, यदि freeमेमोरी ब्लॉक के आकार की आवश्यकता है, तो strdupकिसी तरह एक (पॉइंटर) के बजाय दो मान (पॉइंटर + आकार) वापस करने होंगे, और सी एकल-मूल्य रिटर्न की तुलना में कई-कई गुना अधिक बोझिल बनाता है। इसके बजाय char *strdup(char *)हमें लिखना होगा char *strdup(char *, size_t *)वरना struct CharPWithSize { char *val; size_t size}; CharPWithSize strdup(char *)। (आजकल वह दूसरा विकल्प बहुत आकर्षक लग रहा है, क्योंकि हम जानते हैं कि एनयूएल-टर्मिनेटेड स्ट्रिंग्स "कंप्यूटिंग के इतिहास में सबसे भयावह डिजाइन बग" हैं, लेकिन यह एक दृष्टिहीनता है। 70 के दशक में वापस, सी को एक साधारण के रूप में तार को संभालने की क्षमता char *वास्तव में पास्कल और अल्गोल जैसे प्रतियोगियों पर एक परिभाषित लाभ माना जाता था ।) प्लस, यह सिर्फ strdupइस समस्या से ग्रस्त नहीं है - यह हर प्रणाली को प्रभावित करता है- या उपयोगकर्ता-परिभाषित। समारोह जो ढेर स्मृति आवंटित करता है।

शुरुआती यूनिक्स डिजाइनर बहुत चतुर लोग थे, और कई कारण हैं कि क्यों मूल रूप freeसे बेहतर है mfreeमूल रूप से मुझे लगता है कि प्रश्न का उत्तर यह है कि उन्होंने इस पर ध्यान दिया और तदनुसार अपनी प्रणाली तैयार की। मुझे संदेह है कि जिस समय उन्होंने यह निर्णय लिया उस समय उनके सिर के अंदर क्या चल रहा था, इसका कोई प्रत्यक्ष रिकॉर्ड आपको मिल जाएगा। लेकिन हम कल्पना कर सकते हैं।

प्रीटेंड करें कि आप सी में एप्लिकेशन लिख रहे हैं V6 यूनिक्स पर चलाने के लिए, इसके दो-तर्क के साथ mfree। आपने अब तक ठीक प्रबंधित किया है, लेकिन इन पॉइंटर आकारों का ध्यान रखना अधिक परेशानी का कारण बन रहा है क्योंकि आपके कार्यक्रम अधिक महत्वाकांक्षी हो जाते हैं और ढेर आवंटित चर का अधिक से अधिक उपयोग करने की आवश्यकता होती है। लेकिन फिर आपके पास एक शानदार विचार है: size_tहर समय इन चारों ओर नकल करने के बजाय , आप बस कुछ उपयोगिता कार्य लिख सकते हैं, जो आवंटित स्मृति के अंदर सीधे आकार को रोकते हैं:

void *my_alloc(size_t size) {
    void *block = malloc(sizeof(size) + size);
    *(size_t *)block = size;
    return (void *) ((size_t *)block + 1);
}
void my_free(void *block) {
    block = (size_t *)block - 1;
    mfree(block, *(size_t *)block);
}

और इन नए कार्यों का उपयोग करके आप जितना अधिक कोड लिखेंगे, वे उतने ही भयानक लगेंगे। न केवल वे आपके कोड को लिखना आसान बनाते हैं, वे आपके कोड को भी तेज़ बनाते हैं - दो चीजें जो अक्सर एक साथ नहीं चलती हैं! इससे पहले कि आप इन स्थानों पर size_tचारों ओर से गुजर रहे थे , जिसमें नकल के लिए सीपीयू ओवरहेड जोड़ा गया था, और इसका मतलब था कि आपको अधिक बार रजिस्टर करना होगा (अतिरिक्त कार्य तर्कों के लिए) और व्यर्थ मेमोरी (क्योंकि नेस्टेड फ़ंक्शन कॉल अक्सर परिणाम देगा। size_tविभिन्न स्टैक फ्रेम में संग्रहीत होने की कई प्रतियों में )। अपने नए सिस्टम में, आपको अभी भी मेमोरी को स्टोर करने के लिए खर्च करना होगाsize_t, लेकिन केवल एक बार, और यह कहीं भी नकल नहीं करता है। ये छोटी क्षमता की तरह लग सकते हैं, लेकिन ध्यान रखें कि हम 256 केबी की रैम के साथ उच्च अंत मशीनों के बारे में बात कर रहे हैं।

यह आपको खुश करता है! तो आप दाढ़ी वाले पुरुषों के साथ अपनी शांत चाल साझा करते हैं जो अगले यूनिक्स रिलीज़ पर काम कर रहे हैं, लेकिन यह उन्हें खुश नहीं करता है, यह उन्हें दुखी करता है। आप देखते हैं, वे जैसे नए उपयोगिता कार्यों का एक गुच्छा जोड़ने की प्रक्रिया में थे strdup, और उन्हें पता चलता है कि आपके शांत चाल का उपयोग करने वाले लोग अपने नए कार्यों का उपयोग नहीं कर पाएंगे, क्योंकि उनके नए कार्य सभी बोझिल सूचक + आकार का उपयोग करते हैं एपीआई। और फिर यह आपको दुखी भी करता है, क्योंकि आपको एहसास होता है कि आपको strdup(char *)सिस्टम प्रोग्राम का उपयोग करने में सक्षम होने के बजाय आपके द्वारा लिखे गए प्रत्येक प्रोग्राम में अच्छे कार्य को फिर से लिखना होगा ।

लेकिन रुकें! यह 1977 है, और 5 साल के लिए पीछे की संगतता का आविष्कार नहीं किया जाएगा! और इसके अलावा, कोई भी गंभीर वास्तव में इस अस्पष्ट "यूनिक्स" चीज़ का उपयोग अपने ऑफ-कलर नाम के साथ नहीं करता है। K & R का पहला संस्करण अब प्रकाशक के पास है, लेकिन यह कोई समस्या नहीं है - यह पहले पृष्ठ पर सही कहता है कि "C वर्ण संरेखण जैसी समग्र वस्तुओं से सीधे निपटने के लिए कोई संचालन प्रदान नहीं करता है ... कोई ढेर नहीं है ... "। इतिहास में इस बिंदु पर, string.hऔर mallocविक्रेता एक्सटेंशन (!) हैं। तो, दाढ़ी वाले आदमी # 1 का सुझाव देता है, हम उन्हें पसंद कर सकते हैं लेकिन हम उन्हें पसंद करते हैं; क्यों हम सिर्फ अपने मुश्किल आवंटनकर्ता को आधिकारिक आवंटनकर्ता घोषित नहीं करते हैं ?

कुछ दिनों बाद, दाढ़ी वाले आदमी # 2 नए एपीआई को देखता है और कहता है कि रुको, यह पहले से बेहतर है, लेकिन यह अभी भी आकार के भंडारण के प्रति आवंटन का एक पूरा शब्द खर्च कर रहा है। वह इसे ईश निंदा की अगली बात मानते हैं। हर कोई उसे देखता है जैसे वह पागल है, क्योंकि आप और क्या कर सकते हैं? उस रात वह देर तक रहता है और एक नए आवंटनकर्ता का आविष्कार करता है जो आकार को बिल्कुल भी संग्रहीत नहीं करता है, लेकिन इसके बजाय सूचक मान पर काले जादू बिटशफ्ट्स का प्रदर्शन करके मक्खी पर इसे सीमित करता है, और नए एपीआई को जगह में रखते हुए इसे स्वैप करता है। नए एपीआई का मतलब है कि कोई भी स्विच को नोटिस नहीं करता है, लेकिन वे नोटिस करते हैं कि अगली सुबह कंपाइलर 10% कम रैम का उपयोग करता है।

और अब हर कोई खुश है: आपको अपना आसान लिखने और तेज कोड प्राप्त करने के लिए, दाढ़ी वाले आदमी # 1 को एक अच्छा सरल लिखना है strdupजो लोग वास्तव में उपयोग करेंगे, और दाढ़ी वाले आदमी # 2 - विश्वास है कि उसने अपने बिट को बनाए रखा है - - quines के साथ खिलवाड़ करने के लिए वापस चला जाता है । इसे भेज दो!

या कम से कम, कि यह कैसे हो सकता है।


14
Err, अगर यह स्पष्ट नहीं है, तो यह कलात्मक सकारात्मकता प्रदान करने के लिए फेंके गए विस्तार को पुष्ट करने के साथ, कल्पना की उड़ान है। जीवित या मृत व्यक्तियों के लिए कोई समानता विशुद्ध रूप से है क्योंकि हर किसी में शामिल थोड़े ही दिखते थे । कृपया वास्तविक इतिहास के साथ भ्रमित न करें।
नथानिएल जे। स्मिथ

5
तुम जीते। यह मुझे सबसे प्रशंसनीय स्पष्टीकरण (और लेखन का सबसे अच्छा टुकड़ा) लगता है। भले ही यहां सब कुछ गलत या अमान्य साबित हो, लेकिन दाढ़ी वाले पुरुषों के उत्कृष्ट चित्रण के लिए यह सबसे अच्छा जवाब है।
जयमेर - मोनिका

वाह, इस पृष्ठ पर एक उत्तर जो वास्तव में प्रशंसनीय लगता है। मुझ से +1।
user541686

इससे भी बेहतर - इस पृष्ठ पर एक उत्तर जो वास्तव में सुखद है! साथ ही +1।
डेविड सी। रैंकिन

मुझे आश्चर्य है कि यदि कोई उल्लेखनीय पास्कल सिस्टम माइक्रो कंप्यूटर बेसिक दुभाषियों के समान एक कचरा-एकत्र स्ट्रिंग पूल का उपयोग करता है? C का शब्दार्थ ऐसी चीज़ के साथ काम नहीं करेगा, लेकिन पास्कल में ऐसी चीज़ को बहुत अच्छी तरह से संभाला जा सकता है यदि कोड में ट्रेस करने योग्य स्टैक फ्रेम (जो कई संकलक ने किसी भी तरह से बनाए रखा है) को बनाए रखा जाए।
सुपरकैट

31

" freeसी में बाइट की संख्या को मुक्त करने के लिए क्यों नहीं लेता है?"

क्योंकि इसके लिए कोई ज़रूरत नहीं है, और यह वैसे भी काफी मायने नहीं रखेगा

जब आप कुछ आवंटित करते हैं, तो आप सिस्टम को बताना चाहते हैं कि कितने बाइट्स आवंटित करने हैं (स्पष्ट कारणों के लिए)।

हालाँकि, जब आप अपनी वस्तु पहले ही आवंटित कर चुके होते हैं, तो आपको वापस मिलने वाले मेमोरी क्षेत्र का आकार अब निर्धारित हो जाता है। यह निहित है। यह स्मृति का एक सन्निहित ब्लॉक है। आप इसका कुछ हिस्सा नहीं दे सकते हैं (चलो भूल जाते हैं realloc(), कि यह वैसे भी क्या कर रहा है), आप केवल पूरी बात को ही निपटा सकते हैं आप "एक्स बाइट्स" को निपटा नहीं सकते - या तो आप उस मेमोरी ब्लॉक से मुक्त हो गए जो आपको मिला था malloc()या आप नहीं।

और अब, यदि आप इसे मुक्त करना चाहते हैं, तो आप बस मेमोरी मैनेजर सिस्टम को बता सकते हैं: "यहां यह पॉइंटर है, free()जिस ब्लॉक को इंगित कर रहा है।" - और मेमोरी मैनेजर को पता होगा कि कैसे करना है, या तो क्योंकि यह स्पष्ट रूप से आकार को जानता है, या क्योंकि उसे आकार की आवश्यकता भी नहीं है।

उदाहरण के लिए, malloc()मेमोरी ब्लॉक को मुक्त और आवंटित करने के लिए पॉइंटर्स की लिंक की गई सूची को बनाए रखने के सबसे विशिष्ट कार्यान्वयन । यदि आप एक पॉइंटर को पास करते हैं free(), तो यह उस पॉइंटर को "आवंटित" सूची में खोजेगा, संबंधित नोड को लिंक करेगा और इसे "फ्री" सूची में संलग्न करेगा। यह भी क्षेत्र के आकार की जरूरत नहीं थी। यह केवल उस जानकारी की आवश्यकता होगी जब यह संभावित रूप से ब्लॉक को फिर से उपयोग करने का प्रयास करता है।


अगर मैं आपसे 100 डॉलर उधार लेता हूं और फिर आपसे 100 डॉलर उधार लेता हूं और फिर पांच बार ऐसा करता हूं, तो क्या आपको वास्तव में परवाह है कि मैंने आपसे सात बार पैसे उधार लिए हैं (जब तक कि आप वास्तव में ब्याज नहीं ले रहे हैं!) ?? या क्या आपको सिर्फ इस बात की परवाह है कि मैंने आपसे $ 700 उधार लिए हैं? यहाँ एक ही बात: सिस्टम केवल स्मृति के बारे में परवाह करता है जो असंबद्ध है, यह आवंटित मेमोरी को कैसे विभाजित किया जाता है, इसके बारे में परवाह नहीं करता है (और इसकी आवश्यकता नहीं है)।
user541686

1
@ मेहरदाद: नहीं, और यह नहीं है। सी, हालांकि, करता है। इसका पूरा उद्देश्य चीजों (थोड़ा) को सुरक्षित बनाना है। मैं वास्तव में नहीं जानता कि आप यहाँ क्या देख रहे हैं।
ऑर्बिट

12
@ user3477950: इसे बाइट्स की संख्या को पारित करने की आवश्यकता नहीं है : हाँ, क्योंकि यह इस तरह से डिज़ाइन किया गया था। ओपी ने पूछा कि इसे इस तरह से क्यों बनाया गया?
डेडुप्लिकेटर

5
"क्योंकि यह करने की आवश्यकता नहीं है" - यह बस के रूप में अच्छी तरह से डिजाइन किया जा सकता था ताकि इसकी आवश्यकता हो।
user253751

5
@ मेहरदाद कि पूरी तरह से अस्पष्ट और दोषपूर्ण उपमा। यदि आप एक सौ बार 4 बाइट आवंटित करते हैं, तो यह निश्चित रूप से वास्तव में मायने रखता है कि आप किसे मुक्त करते हैं। 1 को मुक्त करना दूसरे को मुक्त करने के समान नहीं है। दूसरी ओर पैसे के साथ यह कोई फर्क नहीं पड़ता कि आप पहले या दूसरे उधार को
चुकाते हैं

14

C, C ++ की तरह "अमूर्त" नहीं हो सकता है, लेकिन यह अभी भी असेंबली पर अमूर्त होने का इरादा है। उस अंत तक, निम्नतम-स्तरीय विवरण समीकरण से बाहर ले जाया जाता है। यह आपको अधिकांश भाग के लिए संरेखण और पैडिंग के साथ फुस्स होने से रोकता है, जो आपके सभी सी कार्यक्रमों को गैर-पोर्टेबल बना देगा।

संक्षेप में, यह एक अमूर्त लेखन का संपूर्ण बिंदु है


9
निश्चित नहीं है कि इसके साथ क्या संरेखण या पैडिंग करना है। जवाब वास्तव में कुछ भी जवाब नहीं देता है।
user541686

1
@ मेहरदाद सी एक x86 भाषा नहीं है, यह पोर्टेबल होने की कोशिश करता है (कम या ज्यादा) और इस तरह उस महत्वपूर्ण बोझ के प्रोग्रामर को मुक्त करता है। आप उस स्तर तक वैसे भी कई अन्य तरीकों (जैसे इनलाइन असेंबली) तक पहुंच सकते हैं, लेकिन अमूर्तता महत्वपूर्ण है। मैं इस जवाब से सहमत हूं।
मार्को ए।

4
@ मेहरदाद: यदि आपने mallocएन बाइट्स के लिए कहा और इसके बजाय एक सूचक को पूरे पृष्ठ की शुरुआत में लौटा दिया (क्योंकि संरेखण, पैडिंग, या अन्य बाधाओं के कारण , उपयोगकर्ता के पास इसका ट्रैक रखने के लिए कोई रास्ता नहीं होगा - उन्हें मजबूर करना क्या यह
प्रतिशोधी

3
@MichaelFoukarakis: mallocहमेशा आवंटन के आकार को संग्रहीत किए बिना हमेशा एक संरेखित सूचक लौटा सकता है। freeतब सब कुछ ठीक से मुक्त हो यह सुनिश्चित करने के लिए उपयुक्त संरेखण के लिए गोल हो सकता है। मैं नहीं देखता कि समस्या कहाँ है।
user541686

6
@ मेहरदाद: आपके द्वारा बताए गए अतिरिक्त काम का कोई लाभ नहीं है। इसके अतिरिक्त, कीड़े के दूसरे स्रोत sizeको freeखोलने के लिए एक पैरामीटर पास करना ।
माइकल फौकरीस

14

दरअसल, प्राचीन यूनिक्स कर्नेल मेमोरी एलोकेटर में, mfree()एक sizeतर्क लिया । malloc()और mfree()दो सरणियों (कोर मेमोरी के लिए एक, स्वैप के लिए एक और) को रखा गया जिसमें निशुल्क ब्लॉक पते और आकारों की जानकारी थी।

यूनिक्स V6 (प्रोग्राम सिर्फ उपयोग करेगा sbrk()) तक कोई भी उपयोगकर्ता आवंटन नहीं था । यूनिक्स वी 6 में, आईओलिब के साथ एक एलोकेटर alloc(size)और एक free()कॉल शामिल था जिसमें आकार का तर्क नहीं था। प्रत्येक मेमोरी ब्लॉक अपने आकार और अगले ब्लॉक के लिए एक पॉइंटर से पहले था। सूचक का उपयोग केवल नि: शुल्क ब्लॉकों पर किया गया था, जब मुफ्त सूची चल रही थी, और इन-उपयोग ब्लॉकों पर ब्लॉक मेमोरी के रूप में पुन: उपयोग किया गया था।

यूनिक्स 32 वी में और यूनिक्स वी 7 में, इसे एक नए malloc()और free()कार्यान्वयन द्वारा प्रतिस्थापित किया गया था , जहां free()एक sizeतर्क नहीं लिया गया था । कार्यान्वयन एक परिपत्र सूची थी, प्रत्येक चंक को एक शब्द से पहले किया गया था जिसमें अगले चंक के लिए एक संकेतक था, और एक "व्यस्त" (आवंटित) बिट। इसलिए, malloc()/free()एक स्पष्ट आकार का भी ध्यान न रखें।


10

freeC, बाइट्स की संख्या को मुक्त करने के लिए क्यों नहीं लेता है?

क्योंकि इसकी आवश्यकता नहीं है। जानकारी पहले से ही आंतरिक प्रबंधन में उपलब्ध है।

यहाँ दो विचार हैं (जो इस निर्णय में योगदान दे भी सकते हैं और नहीं भी):

  • आप एक फंक्शन की उम्मीद क्यों करेंगे जो एक पैरामीटर प्राप्त करने की आवश्यकता नहीं है?

    (यह गतिशील मेमोरी पर निर्भर लगभग सभी क्लाइंट कोड को जटिल करेगा , और आपके आवेदन में पूरी तरह से अनावश्यक अतिरेक जोड़ देगा)। पॉइंटर आवंटन पर नज़र रखना पहले से ही एक समस्या है। संबद्ध आकारों के साथ मेमोरी आवंटन का ट्रैक रखने से ग्राहक कोड की जटिलता अनावश्यक रूप से बढ़ जाएगी।

  • freeइन मामलों में परिवर्तित कार्य क्या करेगा ?

    void * p = malloc(20);
    free(p, 25); // (1) wrong size provided by client code
    free(NULL, 10); // (2) generic argument mismatch
    

    क्या यह मुफ़्त नहीं होगा (स्मृति रिसाव का कारण?) दूसरे पैरामीटर पर ध्यान न दें? बाहर निकलें कॉल करके एप्लिकेशन को रोकें? इसे लागू करने से आपके आवेदन में अतिरिक्त विफलता बिंदु जुड़ जाएंगे, एक ऐसी सुविधा के लिए जिसकी आपको शायद ज़रूरत नहीं है (और यदि आपको इसकी आवश्यकता है, तो मेरा अंतिम बिंदु नीचे देखें - "आवेदन स्तर पर समाधान लागू करना")।

बल्कि, मैं जानना चाहता हूं कि पहले इस तरह से मुक्त क्यों बनाया गया था।

क्योंकि ऐसा करने का यह "उचित" तरीका है। एक एपीआई को उन तर्कों की आवश्यकता होनी चाहिए जो इसे निष्पादित करने की आवश्यकता है, और इससे अधिक नहीं

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

इसे लागू करने के उचित तरीके हैं:

  • (सिस्टम स्तर पर) मॉलॉक के कार्यान्वयन के भीतर - प्राप्त आकार के आधार पर, विभिन्न रणनीतियों का आंतरिक रूप से उपयोग करने के लिए लाइब्रेरी के कार्यान्वयनकर्ता को लाइब्रेरी लिखने से रोकना नहीं है।

  • (एप्लिकेशन स्तर पर) अपने स्वयं के एपीआई के भीतर मॉलॉक और मुफ्त रैपिंग करके, और इसके बजाय उन का उपयोग करना (आपके आवेदन में हर जगह जिसकी आपको आवश्यकता हो सकती है)।


6
@ user3477950: इसे बाइट्स की संख्या को पारित करने की आवश्यकता नहीं है : हाँ, क्योंकि यह इस तरह से डिज़ाइन किया गया था। ओपी ने पूछा कि इसे इस तरह से क्यों बनाया गया?
डेडुप्लिकेटर

4
"क्योंकि यह करने की आवश्यकता नहीं है" - यह बस के रूप में अच्छी तरह से डिजाइन किया जा सकता है ताकि यह उस जानकारी को बचाने के द्वारा की जरूरत नहीं है।
user253751

1
आपकी बात 2 के अनुसार, आप मुझे सोच रहे हैं कि क्या मुफ्त (NULL) परिभाषित व्यवहार है। अहा, "सी लाइब्रेरी के सभी मानकों के अनुरूप संस्करण नि: शुल्क (NULL) को नो-ऑप
मानते हैं

10

पांच कारणों से वसंत:

  1. यह आसान है। यह प्रोग्रामर से ओवरहेड के पूरे भार को हटा देता है और त्रुटियों को ट्रैक करने के लिए अत्यंत कठिन वर्ग से बचा जाता है।

  2. यह एक ब्लॉक का हिस्सा जारी करने की संभावना को खोलता है। लेकिन चूंकि स्मृति प्रबंधक आमतौर पर ट्रैकिंग जानकारी रखना चाहते हैं, इसलिए यह स्पष्ट नहीं है कि इसका क्या मतलब होगा?

  3. हल्की दौड़ कक्षा में गद्दी और संरेखण के बारे में है। स्मृति प्रबंधन की प्रकृति का अर्थ है कि आवंटित वास्तविक आकार संभवतः आपके द्वारा पूछे गए आकार से भिन्न है। इसका मतलब यह है कि freeआकार की आवश्यकता होती है और साथ ही साथ mallocआवंटित वास्तविक आकार को वापस करने के लिए एक स्थान को बदलना होगा।

  4. यह स्पष्ट नहीं है कि आकार में गुजरने का कोई वास्तविक लाभ है, वैसे भी। एक विशिष्ट मेमोरी मैनेजर में मेमोरी के प्रत्येक भाग के लिए हेडर के 4-16 बाइट्स होते हैं, जिसमें आकार शामिल होता है। यह चंक हेडर आवंटित और असंबद्ध मेमोरी के लिए सामान्य हो सकता है और जब आसन्न विराम मुक्त आते हैं तो उन्हें एक साथ ढहाया जा सकता है। यदि आप कॉलर मेमोरी को मुफ्त मेमोरी स्टोर कर रहे हैं, तो आप आवंटित मेमोरी में एक अलग आकार के क्षेत्र में नहीं होने के कारण संभवतः 4 बाइट्स प्रति चंक कर सकते हैं, लेकिन उस आकार फ़ील्ड को संभवतः वैसे भी प्राप्त नहीं किया जाता है क्योंकि कॉलर को इसे कहीं स्टोर करने की आवश्यकता होती है। लेकिन अब यह जानकारी हेडर चंक में अनुमानित रूप से स्थित होने के बजाय मेमोरी में बिखरी हुई है, जो वैसे भी कम परिचालन रूप से कुशल होने की संभावना है।

  5. यहां तक ​​कि अगर यह अधिक कुशल था, तो यह मौलिक रूप से संभावना नहीं है कि आपका कार्यक्रम वैसे भी स्मृति को मुक्त करने के लिए बड़ी मात्रा में खर्च कर रहा है, इसलिए लाभ छोटा होगा।

संयोग से, विभिन्न आकार की वस्तुओं के लिए अलग-अलग आवंटनकर्ताओं के बारे में आपका विचार इस जानकारी के बिना आसानी से लागू किया जाता है (आप यह निर्धारित करने के लिए पते का उपयोग कर सकते हैं कि आवंटन कहाँ है)। यह नियमित रूप से C ++ में किया जाता है।

बाद में जोड़ा गया

एक और जवाब, बल्कि हास्यास्पद रूप से, इस तरह काम कर सकता है कि सबूत के रूप में एसटीडी :: आवंटनकर्ता लाया है free, लेकिन वास्तव में, यह freeइस तरह से काम नहीं करता है, इसका एक अच्छा उदाहरण के रूप में कार्य करता है। वहाँ क्या दोनों के बीच प्रमुख अंतर हैं malloc/ freeकरते हैं और क्या std :: संभाजक करता है। सबसे पहले, mallocऔर freeउपयोगकर्ता का सामना कर रहे हैं - वे सामान्य प्रोग्रामर के साथ काम std::allocatorकरने के लिए डिज़ाइन किए गए हैं - जबकि मानक पुस्तकालय को विशेषज्ञ मेमोरी आवंटन प्रदान करने के लिए डिज़ाइन किया गया है। यह एक अच्छा उदाहरण प्रदान करता है जब मेरे अंकों में से पहला, कोई फर्क नहीं पड़ता या नहीं। चूंकि यह एक पुस्तकालय है, ट्रैकिंग आकार की जटिलताओं को संभालने की कठिनाइयों को वैसे भी उपयोगकर्ता से छिपाया जाता है।

दूसरे, std :: एलोकेटर हमेशा एक ही आकार के आइटम के साथ काम करता है इसका मतलब यह है कि मूल रूप से पारित संख्या का उपयोग करके यह निर्धारित करना संभव है कि यह कितना मुफ्त है। क्यों यह freeअपने आप में भिन्न है में std::allocatorइसलिए वे हमेशा संरेखण आवश्यकताओं की ही तरह है आइटम आवंटित किया जाना ही है, जाना जाता है, आकार और हमेशा मद की एक ही तरह के हमेशा से रहे हैं। इसका मतलब यह है कि आवंटनकर्ता को शुरुआत में इन वस्तुओं की एक सरणी आवंटित करने और उन्हें आवश्यकतानुसार डोलने के लिए विशेष किया जा सकता है। आप ऐसा नहीं कर सकते हैं freeक्योंकि इस बात की गारंटी देने का कोई तरीका नहीं है कि लौटने के लिए सबसे अच्छा आकार है, जो आकार के लिए पूछा गया है, इसके बजाय यह कभी-कभी कॉल करने वाले की तुलना में बड़े ब्लॉकों को वापस करने के लिए अधिक कुशल है * और इस तरह या तोउपयोगकर्ता या प्रबंधक को वास्तव में दिए गए सटीक आकार को ट्रैक करने की आवश्यकता है । उपयोगकर्ता पर इन प्रकार के कार्यान्वयन विवरणों को पास करना एक अनावश्यक सिरदर्द है जो कॉलर को कोई लाभ नहीं देता है।

- * अगर किसी को अभी भी इस बिंदु को समझने में मुश्किल हो रही है, तो इस पर विचार करें: एक विशिष्ट मेमोरी एलोकेटर एक छोटी मात्रा में ट्रैकिंग जानकारी को मेमोरी ब्लॉक की शुरुआत में जोड़ता है और फिर एक पॉइंटर ऑफसेट को इस से वापस लौटाता है। यहां संग्रहीत जानकारी में आमतौर पर अगले मुक्त ब्लॉक के संकेत शामिल होते हैं, उदाहरण के लिए। मान लें कि हेडर केवल 4 बाइट्स लंबा है (जो वास्तव में अधिकांश वास्तविक पुस्तकालयों से छोटा है), और आकार शामिल नहीं करता है, तो कल्पना करें कि हमारे पास 20 बाइट मुक्त ब्लॉक है जब उपयोगकर्ता 16 बाइट ब्लॉक, एक भोले के लिए पूछता है। सिस्टम 16byte ब्लॉक को लौटाएगा लेकिन फिर एक 4byte टुकड़ा छोड़ देगा जो कभी भी, कभी भी समय बर्बाद करने के लिए इस्तेमाल नहीं किया जा सकता हैmallocकहा जाता है। यदि इसके बजाय प्रबंधक केवल 20 बाइट ब्लॉक लौटाता है तो यह इन गन्दे टुकड़ों को बनने से बचाता है और उपलब्ध स्मृति को अधिक सफाई से आवंटित करने में सक्षम होता है। लेकिन अगर सिस्टम सही ढंग से आकार को ट्रैक किए बिना ऐसा करता है तो हमें उपयोगकर्ता को ट्रैक करने की आवश्यकता होती है - हर, एकल आवंटन के लिए - स्मृति की मात्रा वास्तव में आवंटित की जाती है यदि इसे मुफ्त में पास करना है। एक ही तर्क उन प्रकार / आवंटन के लिए पेडिंग पर लागू होता है जो वांछित सीमाओं से मेल नहीं खाते हैं। इस प्रकार, अधिक से अधिक, freeआकार लेने की आवश्यकता होती है या तो (ए) पूरी तरह से बेकार है क्योंकि मेमोरी एलोकेटर वास्तव में आवंटित आकार से मेल खाने के लिए पारित किए गए आकार पर भरोसा नहीं कर सकता है या (बी) बेकार में उपयोगकर्ता को वास्तविक ट्रैकिंग कार्य करने की आवश्यकता होती है आकार जो आसानी से किसी भी समझदार स्मृति प्रबंधक द्वारा नियंत्रित किया जाएगा।


# 1 सच है। # 2: निश्चित नहीं कि आपका क्या मतलब है। # 3 के बारे में इतना निश्चित नहीं है, संरेखण को अतिरिक्त जानकारी संग्रहीत करने की आवश्यकता नहीं है। # 4 परिपत्र तर्क है; मेमोरी मैनेजरों को केवल उस ओवरहेड की आवश्यकता होती है क्योंकि वे आकार को स्टोर करते हैं, इसलिए आप इसका उपयोग तर्क के रूप में नहीं कर सकते कि वे आकार को क्यों स्टोर करते हैं। और # 5 बहुत डिबेटेबल है।
user541686

मैंने स्वीकार किया और फिर अस्वीकार्य है - यह एक अच्छे उत्तर की तरह लग रहा है, लेकिन सवाल बहुत गतिविधि हो रहा है, मुझे लगता है कि मैं थोड़ा समय से पहले हो सकता था। यह निश्चित रूप से मुझे कुछ सोचने के लिए देता है।
जयमेर -

2
@ अजमेर: हाँ, यह समय से पहले है। मैं स्वीकार करने से पहले एक या दो दिन प्रतीक्षा करने का सुझाव देता हूं, और मैं अपने बारे में सोचने का सुझाव देता हूं। यह वास्तव में एक दिलचस्प सवाल है और सबसे अधिक / सभी उत्तर आपको पहले ऐसे किसी भी "क्यों" के लिए मिलेंगे, StackOverflow पर यह सवाल मौजूदा सिस्टम को सही ठहराने के बजाय अर्ध-स्वचालित प्रयास होगा, जो वास्तव में अंतर्निहित सवाल का समाधान होगा।
user541686

@ मेहरदाद: आपने गलत समझा है कि मैं # 4 में क्या कह रहा हूं। मैं यह नहीं कह रहा हूं कि यह अतिरिक्त आकार लेगा, मैं कह रहा हूं (क) यह स्थानांतरित हो जाएगा जिसे आकार को स्टोर करना है, इसलिए यह वास्तव में किसी भी स्थान को नहीं बचाएगा और (बी) परिणामस्वरूप परिवर्तन वास्तव में इसे बनाने की संभावना है कम कुशल अधिक नहीं। # 5 के रूप में, मुझे यकीन नहीं है कि यह सब पर बहस करने योग्य है: हम - सबसे - मुफ्त कॉल से निर्देशों के एक जोड़े को बचाने के बारे में बात कर रहे हैं। मुफ्त कॉल की लागतों की तुलना में जो न्यूनतम होगी।
जैक ऐडली

1
@ मेहरदाद: ओह, और # 3 पर, नहीं, इसके लिए अतिरिक्त जानकारी की आवश्यकता नहीं है, इसके लिए अतिरिक्त मेमोरी की आवश्यकता है। 16 बाइट संरेखण के साथ काम करने के लिए डिज़ाइन किया गया एक विशिष्ट मेमोरी मैनेजर एक 115 बाइट ब्लॉक के लिए पूछे जाने पर एक पॉइंटर को 128 बाइट ब्लॉक में लौटाएगा। यदि freeकॉल को मुक्त करने के लिए आकार को सही ढंग से पास करना है, तो उसे यह पता होना चाहिए।
जैक आइडली

5

मैं इसे केवल एक उत्तर के रूप में पोस्ट कर रहा हूं क्योंकि यह वह नहीं है जिसकी आप उम्मीद कर रहे हैं, बल्कि इसलिए कि मेरा मानना ​​है कि यह केवल एक ही सही है:

यह संभवतः मूल रूप से सुविधाजनक समझा गया था, और इसके बाद इसमें सुधार नहीं किया जा सका।
इसकी कोई ठोस वजह नहीं है। (लेकिन अगर यह गलत है तो मैं खुशी से इसे हटा दूंगा।)

वहाँ होगा लाभ होगा अगर यह संभव था: आप, जिसका आकार आप पहले से पता था कि स्मृति की एक बड़ी टुकड़ा आवंटित कर सकता है तो एक छोटा सा एक समय में मुक्त - के रूप में बार-बार आवंटन और स्मृति के छोटे-छोटे टुकड़ों को मुक्त करने का विरोध किया। वर्तमान में इस तरह के कार्य संभव नहीं हैं।


आप में से कई (कई 1 !) को लगता है कि आकार को पार करना कितना हास्यास्पद है:

क्या मैं आपको std::allocator<T>::deallocateविधि के लिए C ++ के डिजाइन निर्णय का उल्लेख कर सकता हूं ?

void deallocate(pointer p, size_type n);

इस कॉल से पहले क्षेत्र की सभी वस्तुओं को नष्ट कर दिया जाएगा। इस मेमोरी को प्राप्त करने के लिए पारित मूल्य से मेल खाना चाहिए n Tp
nallocate

मुझे लगता है कि आपके पास इस डिजाइन निर्णय का विश्लेषण करने के बजाय एक "दिलचस्प" समय होगा।


जैसा कि operator delete, यह पता चला है कि 2013 N3778 प्रस्ताव ("C ++ Sized Deallocation") को भी ठीक करने का इरादा है।


1 मूल प्रश्न के तहत टिप्पणियों को देखें कि कितने लोगों ने पैरामीटर की कमी को सही ठहराने के लिए "कॉल के लिए आकार पूरी तरह से बेकार है"free जैसे जल्दबाजी के दावे किए size


5
के लिए malloc()कार्यान्वयन यह भी याद रखना आवश्यकता हटा कुछ भी एक आवंटित क्षेत्र के बारे में, संरेखण भूमि के ऊपर करने के लिए आवंटन भूमि के ऊपर कम करने। malloc()मुक्त किए गए विखंडू के भीतर सभी बहीखाता करने में सक्षम होगा। ऐसे उपयोग-मामले हैं जिनमें यह एक बड़ा सुधार होगा। कई छोटे-छोटे खंडों में मेमोरी के एक बड़े हिस्से को निपटाने को हतोत्साहित करना होगा, हालांकि, इससे बहुत अधिक विखंडन होगा।
विस्फ़ोटक -

1
@ सेमीस्टर: उपयोग के मामले ठीक उसी तरह के थे जिस तरह से मैं जिक्र कर रहा था, आपने सिर पर कील ठोक दी, धन्यवाद। विखंडन के बारे में: यह निश्चित नहीं है कि विकल्प के सापेक्ष विखंडन कैसे बढ़ता है, जो कि छोटे टुकड़ों में आवंटित और मुक्त स्मृति दोनों के लिए है।
user541686

std::allocatorएक विशिष्ट, ज्ञात आकार के केवल तत्वों को आवंटित करता है। यह एक सामान्य प्रयोजन के लिए आवंटन नहीं है, तुलना संतरे के लिए सेब है।
जैक एडली

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

1
@ क्लिफर्ड: बिल्कुल - इसीलिए मैंने कहा कि इसका कोई ठोस कारण नहीं है। यह सिर्फ एक निर्णय है जो किया गया था, और यह मानने का कोई कारण नहीं है कि यह विकल्पों से कड़ाई से बेहतर है।
user541686

2

मॉलॉक और फ्री गो हैंड इन हैंड, प्रत्येक "मॉलोक" को एक "फ्री" द्वारा मैच किया जा रहा है। इस प्रकार यह पूरी तरह से समझ में आता है कि पिछले "मॉलॉक" से मेल खाते "फ्री" को बस उस मॉलोक द्वारा आवंटित मेमोरी की मात्रा को मुक्त करना चाहिए - यह बहुमत का उपयोग मामला है जो 99% मामलों में समझ में आता है। सभी मेमोरी त्रुटियों की कल्पना करें यदि दुनिया भर के सभी प्रोग्रामर द्वारा मॉलॉक / फ्री का उपयोग कभी भी किया जाता है, तो मॉलॉक में आवंटित राशि का ट्रैक रखने के लिए प्रोग्रामर की आवश्यकता होगी, और फिर उसी को मुक्त करना याद रखें। जिस परिदृश्य के बारे में आप बात करते हैं, वह वास्तव में किसी प्रकार के मेमोरी प्रबंधन कार्यान्वयन में कई मॉलस्क / फ़्रीज़ का उपयोग करना चाहिए।


5
मुझे लगता है कि "सभी की कल्पना करें [...] त्रुटियां" मूट है जब आप अन्य बग कारखानों के बारे में सोचते हैं gets, जैसे printf, मैनुअल लूप्स (एक-एक करके), अपरिभाषित व्यवहार, प्रारूप-तार, निहितार्थ रूपांतरण, बिट ट्रिक, एट इत्यादि।
सेबेस्टियन मच

1

मैं सुझाव दूंगा कि यह बहुत सुविधाजनक है क्योंकि इस तरह से (कुछ मामलों में) जानकारी को मैन्युअल रूप से ट्रैक करने के लिए नहीं है और प्रोग्रामर त्रुटि के लिए भी कम संभावना है।

इसके अतिरिक्त, realloc को इस बहीखाता जानकारी की आवश्यकता होगी, जो मुझे उम्मीद है कि आवंटन आकार से अधिक है। यानी यह उस तंत्र को अनुमति देता है जिसके द्वारा यह कार्यान्वयन को परिभाषित करने का काम करता है।

आप अपना खुद का आवंटनकर्ता लिख ​​सकते हैं जो आपके सुझाव के अनुसार कुछ हद तक काम करता है और यह अक्सर विशिष्ट मामलों (विशेष रूप से बड़े पैमाने पर प्रदर्शन लाभ के साथ) के लिए इसी तरह के पूल आवंटन के लिए c ++ में किया जाता है, हालांकि यह आमतौर पर ऑपरेटर के संदर्भ में लागू होता है पूल ब्लॉक आवंटित करने के लिए नया।


1

मैं यह नहीं देखता कि एक आवंटनकर्ता कैसे काम करेगा जो उसके आवंटन के आकार को ट्रैक नहीं करता है। यदि यह ऐसा नहीं करता है, तो यह कैसे पता चलेगा कि भविष्य के mallocअनुरोध को पूरा करने के लिए कौन सी मेमोरी उपलब्ध है ? यह पता लगाने के लिए कम से कम किसी प्रकार के डेटा संरचना को संग्रहीत करता है, जिसमें यह इंगित करने के लिए कि उपलब्ध मेमोरी ब्लॉक कहां हैं। (और निश्चित रूप से, रिक्त स्थानों की एक सूची को संग्रहीत करना आवंटित स्थानों की सूची को संग्रहीत करने के बराबर है)।


यह भी एक स्पष्ट आकार क्षेत्र की जरूरत नहीं है। यह बस अगले ब्लॉक के लिए एक संकेतक हो सकता है, और एक आवंटित बिट।
निंजाल

0

ठीक है, केवल एक चीज जो आपको चाहिए वह एक संकेतक है जिसका उपयोग आप पहले से आवंटित मेमोरी को खाली करने के लिए करेंगे। बाइट्स की मात्रा कुछ ऑपरेटिंग सिस्टम द्वारा प्रबंधित की जाती है, इसलिए आपको इसके बारे में चिंता करने की ज़रूरत नहीं है। यह आवश्यक नहीं होगा कि आवंटित बाइट्स की संख्या मुफ्त में लौटा दी जाए ()। मैं आपको एक रनिंग प्रोग्राम द्वारा आवंटित बाइट्स / पोज़िशन्स की संख्या की गणना करने के लिए एक मैन्युअल तरीका सुझाता हूँ:

यदि आप लिनक्स में काम करते हैं और आप जानना चाहते हैं कि बाइट्स / पोज़िशन्स की मात्रा को आवंटित किया गया है, तो आप एक साधारण प्रोग्राम बना सकते हैं जो एक बार या n बार में मल्कोक का उपयोग करता है और आपके द्वारा प्राप्त पॉइंटर्स को प्रिंट करता है। इसके अलावा, आपको प्रोग्राम को कुछ सेकंड के लिए सोना चाहिए (आपके लिए निम्न करने के लिए पर्याप्त है)। उसके बाद, उस प्रोग्राम को चलाएं, उसके PID को देखें, cd / proc / process_PID लिखें और बस "कैट मैप्स" टाइप करें। आउटपुट आपको दिखाएगा, एक विशिष्ट पंक्ति में, ढेर मेमोरी क्षेत्र की शुरुआत और अंतिम मेमोरी पते (जिस पर आप स्मृति को आवंटित कर रहे हैं)। अनुमान लगा सकते हैं कि आपने कितनी मेमोरी आवंटित की है।

आशा करता हूँ की ये काम करेगा!


0

क्यों करना चाहिए? मॉलोक () और फ्री () जानबूझकर बहुत सरल मेमोरी मैनेजमेंट प्राइमेटीव हैं , और सी में उच्च-स्तरीय मेमोरी प्रबंधन काफी हद तक डेवलपर तक है। टी

इसके अलावा realloc () पहले से ही करता है - यदि आप realloc में आवंटन कम करते हैं () तो यह डेटा को स्थानांतरित नहीं करेगा, और लौटाया गया संकेतक मूल के समान होगा।

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

आपने प्रश्न C ++ के साथ-साथ C को भी टैग किया है, और यदि C ++ वह है जो आप उपयोग कर रहे हैं, तो आपको शायद ही किसी भी मामले में Malloc / मुफ्त का उपयोग करना चाहिए - नए / हटाए जाने के अलावा, STL कंटेनर क्लासेस स्वचालित रूप से मेमोरी का प्रबंधन करते हैं, और एक तरह से संभव है विभिन्न कंटेनरों की प्रकृति के लिए विशेष रूप से उपयुक्त होना चाहिए।


इसके अलावा realloc () पहले से ही करता है - यदि आप realloc में आवंटन कम करते हैं () तो यह डेटा को स्थानांतरित नहीं करेगा, और लौटाया गया संकेतक मूल के समान होगा। क्या यह गारंटीकृत व्यवहार है? यह कई एम्बेडेड आवंटनकर्ताओं में सामान्य प्रतीत होता है, लेकिन मुझे यकीन नहीं था कि यह व्यवहार मानक-ग के हिस्से के रूप में निर्दिष्ट किया गया था।
rsaxvc

@rsaxvc: अच्छा प्रश्न - cplusplus.com दस्तावेज़ "यदि नया आकार बड़ा है, तो नए आवंटित हिस्से का मूल्य अनिश्चित है।" , इसका अर्थ है कि यदि यह छोटा है तो इसका निर्धारण किया जाएगा । [opengroup.org () का कहना है कि "यदि मेमोरी ऑब्जेक्ट के नए आकार में ऑब्जेक्ट की आवाजाही की आवश्यकता होगी, तो ऑब्जेक्ट के पिछले तात्कालिकता के लिए जगह खाली हो जाती है।" - यदि यह छोटा था, तो डेटा को स्थानांतरित करने की आवश्यकता नहीं होगी। फिर से निहितार्थ यह है कि छोटा वास्तविक नहीं होगा। मुझे यकीन नहीं है कि आईएसओ मानक क्या कहता है।
क्लिफर्ड

1
reallocहै बिल्कुल डेटा को स्थानांतरित करने की अनुमति दी। सी मानक के अनुसार यह + + के reallocरूप में लागू करने के लिए पूरी तरह से कानूनी है । और ऐसे अच्छे कारण हैं कि एक कार्यान्वयन एक आवंटन को स्थानांतरित करना चाहता है जो आकार में कम हो गया है, उदाहरण के लिए टुकड़े टुकड़े करने की स्मृति से बचने के लिए। mallocmemcpyfree
नथानिएल जे। स्मिथ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.