सी गतिशील स्मृति आवंटन
C standard library (libc) |
---|
General topics |
Miscellaneous headers |
सी गतिशील स्मृति आवंटन, सी प्रोग्रामिंग भाषा में सी प्रोग्रामिंग भाषा में प्रकार्य के समूह के माध्यम से मॉलोक, रियललोक, कॉलोक, एलायंस_आलोक और निःशुल्कके माध्यम से गतिशील स्मृति आवंटन के लिए मैनुअल मेमोरी प्रबंधन करने को संदर्भित करता है।[1][2][3]
C++ प्रोग्रामिंग भाषा में ये प्रकार्य सम्मिलित हैं; तथापि, ऑपरेटर नए और डिलीट प्रचालक समान कार्यक्षमता प्रदान करते हैं और उस भाषा के लेखकों द्वारा अनुशंसित होते हैं।[4] फिर भी, ऐसी कई स्थितियाँ हैं जिनमें नए/डिलीट का उपयोग करना अनुप्रयोज्य नहीं होता है, जैसे कचरा संग्रहण कोड या प्रदर्शन-संवेदनशील कोड, और उच्च-स्तरीय नए प्रचालक के बदले मॉलोक और नियोजन नए के संयोजन की आवश्यकता हो सकती है।
मॉलोक द्वारा उपयोग किए जाने वाले वास्तविक मेमोरी आवंटन तंत्र के कई अलग-अलग कार्यान्वयन उपलब्ध हैं। निष्पादन समय और आवश्यक स्मृति दोनों में उनका प्रदर्शन भिन्न होता है।
तर्काधार
C (प्रोग्रामिंग लैंग्वेज) मेमोरी स्थैतिक स्मृति आवंटन, स्वचालित मेमोरी आवंटन या डायनेमिक मेमोरी एलोकेशन को मैनेज करता है। स्टेटिक-अवधि चर मुख्य मेमोरी में आवंटित किए जाते हैं, आमतौर पर कार्यक्रम के निष्पादन योग्य कोड के साथ, और कार्यक्रम के जीवनकाल के लिए बने रहते हैं; स्वचालित-अवधि चर कॉल स्टैक पर आवंटित किए जाते हैं और आते हैं और जाते हैं जैसे कार्यों को बुलाया जाता है और वापस आते हैं। स्थैतिक-अवधि और स्वचालित-अवधि चर के लिए, आवंटन का आकार संकलन-समय स्थिर होना चाहिए (चर-लंबाई स्वचालित सरणियों के मामले को छोड़कर)[5]). यदि रन टाइम (प्रोग्राम जीवनचक्र चरण) | रन-टाइम तक आवश्यक आकार ज्ञात नहीं है (उदाहरण के लिए, यदि मनमाना आकार का डेटा उपयोगकर्ता या डिस्क फ़ाइल से पढ़ा जा रहा है), तो निश्चित आकार के डेटा ऑब्जेक्ट का उपयोग करना अपर्याप्त है .
आवंटित स्मृति का जीवनकाल भी चिंता का कारण बन सकता है। सभी स्थितियों के लिए न तो स्थिर- और न ही स्वचालित-अवधि मेमोरी पर्याप्त है। स्वचालित-आवंटित डेटा कई फ़ंक्शन कॉलों में नहीं बना रह सकता है, जबकि स्थिर डेटा प्रोग्राम के जीवन के लिए बना रहता है चाहे इसकी आवश्यकता हो या नहीं। कई स्थितियों में प्रोग्रामर को आबंटित मेमोरी के जीवनकाल के प्रबंधन में अधिक लचीलेपन की आवश्यकता होती है।
डायनेमिक मेमोरी आवंटन का उपयोग करके इन सीमाओं से बचा जाता है, जिसमें मेमोरी अधिक स्पष्ट रूप से (लेकिन अधिक लचीले ढंग से) प्रबंधित होती है, आमतौर पर इसे से आवंटित करके free store (informally called the "heap"),[citation needed] इस उद्देश्य के लिए संरचित स्मृति का एक क्षेत्र। सी में, लाइब्रेरी फ़ंक्शन malloc
हीप पर मेमोरी का एक ब्लॉक आवंटित करने के लिए उपयोग किया जाता है। प्रोग्राम मेमोरी के इस ब्लॉक को एक सूचक (कंप्यूटर प्रोग्रामिंग) के माध्यम से एक्सेस करता है malloc
रिटर्न। जब मेमोरी की आवश्यकता नहीं रह जाती है, तो पॉइंटर को पास किया जाता है free
जो मेमोरी को हटा देता है ताकि इसे अन्य उद्देश्यों के लिए इस्तेमाल किया जा सके।
सी के मूल विवरण ने संकेत दिया कि calloc
और cfree
मानक पुस्तकालय में थे, लेकिन नहीं malloc
. यूनिक्स के लिए भंडारण प्रबंधक के सरल मॉडल कार्यान्वयन के लिए कोड दिया गया था alloc
और free
उपयोगकर्ता इंटरफ़ेस के रूप में कार्य करता है, और का उपयोग कर रहा है sbrk
ऑपरेटिंग सिस्टम से मेमोरी का अनुरोध करने के लिए सिस्टम कॉल।[6] छठा संस्करण यूनिक्स प्रलेखन देता है alloc
और free
निम्न-स्तरीय स्मृति आवंटन कार्यों के रूप में।[7] malloc
ई> और free
दिनचर्या को उनके आधुनिक रूप में पूरी तरह से 7वें संस्करण यूनिक्स मैनुअल में वर्णित किया गया है।[8][9]
कुछ प्लेटफॉर्म पुस्तकालय या आंतरिक फ़ंक्शन कॉल प्रदान करते हैं जो हीप के बजाय सी स्टैक से रन-टाइम डायनेमिक आवंटन की अनुमति देते हैं (उदा। alloca()
[10]). कॉलिंग फ़ंक्शन समाप्त होने पर यह मेमोरी स्वचालित रूप से मुक्त हो जाती है।
कार्यों का अवलोकन
सी डायनेमिक मेमोरी आवंटन कार्यों को परिभाषित किया गया है stdlib.h
हेडर (cstdlib
सी ++ में हेडर)।[1]
Function | Description |
---|---|
malloc
|
allocates the specified number of bytes |
aligned_alloc
|
allocates the specified number of bytes at the specified allignment |
realloc
|
increases or decreases the size of the specified block of memory, moving it if necessary |
calloc
|
allocates the specified number of bytes and initializes them to zero |
free
|
releases the specified block of memory back to the system |
के बीच अंतर malloc()
और calloc()
malloc()
एक तर्क लेता है (बाइट्स में आवंटित करने के लिए स्मृति की मात्रा), जबकिcalloc()
दो तर्क लेता है - तत्वों की संख्या और प्रत्येक तत्व का आकार।malloc()
केवल मेमोरी आवंटित करता है, जबकिcalloc()
आवंटित क्षेत्र में बाइट को आवंटित और शून्य पर सेट करता है।[11]
उपयोग उदाहरण
स्वत: गुंजाइश के साथ दस पूर्णांकों की एक सरणी डेटा संरचना बनाना सी में सीधा है:
<वाक्यविन्यास प्रकाश लैंग = सी>
इंट सरणी [10];
</वाक्यविन्यास हाइलाइट>
तथापि, संकलन समय पर सरणी का आकार तय किया गया है। यदि कोई चर-लंबाई_अरे का उपयोग किए बिना एक समान सरणी को गतिशील रूप से आवंटित करना चाहता है, जो सभी C11 (C मानक संशोधन) कार्यान्वयन में समर्थित होने की गारंटी नहीं है, तो निम्न कोड का उपयोग किया जा सकता है:
<वाक्यविन्यास प्रकाश लैंग = सी>
int *सरणी = malloc(10 * sizeof(int));
</वाक्यविन्यास हाइलाइट>
यह बाइट्स की संख्या की गणना करता है जो स्मृति में दस पूर्णांकों पर कब्जा कर लेता है, फिर अनुरोध करता है कि कई बाइट्स से malloc
और नाम के एक पॉइंटर (कंप्यूटर प्रोग्रामिंग) को रिजल्ट असाइन करता है array
(सी सिंटैक्स के कारण, कुछ स्थितियों में पॉइंटर्स और सरणियों का परस्पर उपयोग किया जा सकता है)।
क्योंकि malloc
अनुरोध की सेवा करने में सक्षम नहीं हो सकता है, यह एक शून्य सूचक लौटा सकता है और यह इसकी जांच करने के लिए सर्वोत्तम प्रथाओं को कोडिंग कर रहा है:
<वाक्यविन्यास प्रकाश लैंग = सी>
int *सरणी = malloc(10 * sizeof(int));
अगर (सरणी == न्यूल) {
fprintf (stderr, malloc विफल \ n); वापसी -1;
}
</वाक्यविन्यास हाइलाइट>
जब प्रोग्राम को गतिशील सरणी की आवश्यकता नहीं होती है, तो उसे अंततः कॉल करना चाहिए free
उस मेमोरी को वापस करने के लिए जो फ्री स्टोर में रहती है:
<वाक्यविन्यास प्रकाश लैंग = सी>
मुक्त (सरणी);
</वाक्यविन्यास हाइलाइट>
स्मृति द्वारा अलग रखा गया malloc
इनिशियलाइज़ेशन (प्रोग्रामिंग) नहीं है और इसमें cruft हो सकता है: पहले उपयोग किए गए और छोड़े गए डेटा के अवशेष। के साथ आवंटन के बाद malloc
, सरणी के तत्व अप्रारंभीकृत चर हैं। आदेश calloc
एक आवंटन लौटाएगा जो पहले ही साफ हो चुका है:
<वाक्यविन्यास प्रकाश लैंग = सी>
int * सरणी = कॉलोक (10, आकार (int));
</वाक्यविन्यास हाइलाइट>
रीयलोक के साथ हम एक पॉइंटर पॉइंट की मेमोरी की मात्रा का आकार बदल सकते हैं। उदाहरण के लिए, यदि हमारे पास आकार की सरणी के रूप में कार्य करने वाला सूचक है और हम इसे आकार की एक सरणी में बदलना चाहते हैं , हम realloc का उपयोग कर सकते हैं। <वाक्यविन्यास प्रकाश लैंग = सी> int *arr = malloc(2 * sizeof(int)); आगमन [0] = 1; आगमन [1] = 2; arr = realloc (arr, 3 * sizeof (int)); आगमन [2] = 3; </वाक्यविन्यास हाइलाइट> ध्यान दें कि realloc को ब्लॉक का आधार पता बदलना चाहिए (यानी यदि यह मूल ब्लॉक के आकार को बढ़ाने में विफल रहा है, और इसलिए कहीं और एक नया बड़ा ब्लॉक आवंटित किया है और इसमें पुरानी सामग्री की प्रतिलिपि बनाई है)। इसलिए, मूल ब्लॉक के भीतर पतों के लिए कोई संकेतक भी अब मान्य नहीं हैं।
प्रकार सुरक्षा
malloc
एक शून्य सूचक लौटाता है (void *
), जो इंगित करता है कि यह अज्ञात डेटा प्रकार के क्षेत्र के लिए सूचक है। मजबूत प्रकार की प्रणाली के कारण सी ++ में कास्टिंग का उपयोग आवश्यक है, जबकि सी में ऐसा नहीं है। कोई इस सूचक को एक विशिष्ट प्रकार के लिए कास्ट कर सकता है (प्रकार रूपांतरण देखें):
<वाक्यविन्यास प्रकाश लैंग = सी> इंट *पीआरटी, *पीआरटी2; पीटीआर = मॉलोक (10 * आकार (* पीटीआर)); / * कास्ट के बिना * / ptr2 = (int *) malloc (10 * sizeof (*ptr)); / * कास्ट के साथ * / </वाक्यविन्यास हाइलाइट>
ऐसी कास्ट करने के फायदे और नुकसान हैं।
कास्ट करने के फायदे
- कलाकारों को सम्मिलित करने से सी प्रोग्राम या फ़ंक्शन को सी ++ के रूप में संकलित करने की अनुमति मिल सकती है।
- कास्ट ANSI C|पूर्व-1989 संस्करणों के लिए अनुमति देता है
malloc
वह मूल रूप से एक लौटाchar *
.Cite error: Closing</ref>
missing for<ref>
tag).
कास्टिंग करने के नुकसान
- सी मानक के तहत, कास्ट बेमानी है।
- कास्ट जोड़ने से शीर्षलेख सम्मिलित करने में विफल हो सकता है
stdlib.h
, जिसमें फ़ंक्शन प्रोटोटाइप के लिएmalloc
पाया जाता है।[12][13] के लिए एक प्रोटोटाइप के अभाव मेंmalloc
, C90 मानक के लिए आवश्यक है कि C कंपाइलर मान लेmalloc
एक देता हैint
. यदि कोई कास्ट नहीं है, तो C90 को डायग्नोस्टिक की आवश्यकता होती है जब यह पूर्णांक पॉइंटर को सौंपा जाता है; तथापि, कलाकारों के साथ, इस निदान का उत्पादन नहीं किया जाएगा, एक बग को छिपाते हुए। कुछ आर्किटेक्चर और डेटा मॉडल पर (जैसे 64-बिट सिस्टम पर LP64, जहांlong
और पॉइंटर्स 64-बिट हैं औरint
32-बिट है), यह त्रुटि वास्तव में अपरिभाषित व्यवहार का परिणाम हो सकती है, जैसा कि स्पष्ट रूप से घोषित किया गया हैmalloc
32-बिट मान लौटाता है जबकि वास्तव में परिभाषित फ़ंक्शन 64-बिट मान लौटाता है। कॉलिंग कन्वेंशन और मेमोरी लेआउट के आधार पर, इसका परिणाम ढेर तोड़ना हो सकता है। आधुनिक कंपाइलरों में इस मुद्दे पर किसी का ध्यान नहीं जाने की संभावना कम है, क्योंकि C99 निहित घोषणाओं की अनुमति नहीं देता है, इसलिए कंपाइलर को डायग्नोस्टिक का उत्पादन करना चाहिए, भले ही वह मान लेint
वापस करना। - यदि इसकी घोषणा पर सूचक का प्रकार बदल दिया गया है, तो किसी को भी सभी पंक्तियों को बदलने की आवश्यकता हो सकती है
malloc
बुलाया और डाला जाता है।
सामान्य त्रुटियाँ
डायनेमिक मेमोरी आवंटन का अनुचित उपयोग अक्सर बग का स्रोत हो सकता है। इनमें सुरक्षा बग या प्रोग्राम क्रैश सम्मिलित हो सकते हैं, जो अक्सर सेगमेंटेशन दोषों के कारण होते हैं।
सबसे आम त्रुटियां इस प्रकार हैं:[14]
आवंटन विफलताओं की जांच नहीं करना: स्मृति आवंटन सफल होने की गारंटी नहीं है, और इसके बजाय एक शून्य सूचक लौटा सकता है। यदि आबंटन सफल है, तो जाँच किए बिना दिए गए मान का उपयोग करना, अपरिभाषित व्यवहार को आमंत्रित करता है। यह आमतौर पर दुर्घटना की ओर जाता है (नल पॉइंटर डिरेफरेंस पर परिणामी विभाजन दोष के कारण), लेकिन इस बात की कोई गारंटी नहीं है कि क्रैश होगा इसलिए उस पर भरोसा करने से भी समस्याएँ हो सकती हैं।
मेमोरी लीक: मेमोरी का उपयोग करने में विफलता free
गैर-पुन: प्रयोज्य मेमोरी का निर्माण होता है, जो अब प्रोग्राम द्वारा उपयोग नहीं किया जाता है। यह स्मृति संसाधनों को बर्बाद करता है और इन संसाधनों के समाप्त होने पर आवंटन विफल हो सकता है।
तार्किक त्रुटियां: सभी आवंटनों को एक ही पैटर्न का पालन करना चाहिए: आवंटन का उपयोग करना malloc
, डेटा स्टोर करने के लिए उपयोग, डीलोकेशन का उपयोग करना free
. इस पैटर्न का पालन करने में विफलता, जैसे कॉल करने के बाद मेमोरी उपयोग free
(झूलने वाला सूचक) या कॉल करने से पहले malloc
(जंगली सूचक), बुला रहा है free
दो बार (डबल फ्री), आदि, आमतौर पर एक विभाजन दोष का कारण बनता है और प्रोग्राम के क्रैश होने का परिणाम होता है। ये त्रुटियां क्षणिक और डिबग करने में कठिन हो सकती हैं - उदाहरण के लिए, मुक्त मेमोरी को आमतौर पर OS द्वारा तुरंत पुनः प्राप्त नहीं किया जाता है, और इस प्रकार लटकने वाले पॉइंटर्स थोड़ी देर के लिए बने रह सकते हैं और काम करने लगते हैं।
इसके अलावा, एएनएसआई सी मानकीकरण से पहले एक इंटरफ़ेस के रूप में, malloc
और इसके संबंधित कार्यों में ऐसे व्यवहार होते हैं जिन्हें जानबूझकर स्वयं के लिए परिभाषित करने के लिए कार्यान्वयन के लिए छोड़ दिया गया था। उनमें से एक शून्य-लंबाई आवंटन है, जो कि अधिक समस्या है realloc
चूंकि शून्य का आकार बदलना अधिक सामान्य है।[15] हालाँकि POSIX और सिंगल यूनिक्स विशिष्टता दोनों को वापस लौटकर 0-आकार के आवंटन के उचित प्रबंधन की आवश्यकता होती है NULL
या कुछ और जिसे सुरक्षित रूप से मुक्त किया जा सकता है,[16] सभी प्लेटफॉर्म के लिए इन नियमों का पालन करना आवश्यक नहीं है। इसके कारण होने वाली कई डबल-फ्री त्रुटियों में, 2019 व्हाट्सप्प आरसीई विशेष रूप से प्रमुख था।[17] इन कार्यों को लपेटने का एक तरीका उन्हें सुरक्षित बनाने के लिए केवल 0-आकार के आवंटन की जाँच करना और उन्हें आकार 1 में बदलना है। (रिटर्निंग) NULL
इसकी अपनी समस्याएँ हैं: यह अन्यथा एक आउट-ऑफ़-मेमोरी विफलता का संकेत देता है। के मामले में realloc
यह संकेत देगा कि मूल स्मृति को स्थानांतरित और मुक्त नहीं किया गया था, जो फिर से आकार 0 के मामले में नहीं है, जिससे डबल-फ्री हो जाता है।)[18]
कार्यान्वयन
स्मृति प्रबंधन का कार्यान्वयन काफी हद तक ऑपरेटिंग सिस्टम और आर्किटेक्चर पर निर्भर करता है। कुछ ऑपरेटिंग सिस्टम मॉलोक के लिए आवंटक की आपूर्ति करते हैं, जबकि अन्य डेटा के कुछ क्षेत्रों को नियंत्रित करने के लिए कार्यों की आपूर्ति करते हैं। एक ही डायनेमिक मेमोरी एलोकेटर का उपयोग अक्सर दोनों को लागू करने के लिए किया जाता है malloc
और संचालिका new
सी ++ में।[19]
हीप-आधारित
एलोकेटर का कार्यान्वयन आमतौर पर ढेर स्मृति या डेटा खंड का उपयोग करके किया जाता है। आवंटक आमतौर पर आवंटन अनुरोधों को पूरा करने के लिए ढेर का विस्तार और अनुबंध करेगा।
ढेर विधि कुछ अंतर्निहित खामियों से ग्रस्त है, जो पूरी तरह से विखंडन (कंप्यूटर) से उपजी है। स्मृति आबंटन की किसी भी विधि की तरह, हीप खंडित हो जाएगा; यानी, ढेर पर आवंटित स्थान में प्रयुक्त और अप्रयुक्त स्मृति के खंड होंगे। ढेर का विस्तार करने का सहारा लेने से पहले एक अच्छा आवंटक उपयोग करने के लिए पहले से आवंटित स्मृति के अप्रयुक्त क्षेत्र को खोजने का प्रयास करेगा। इस पद्धति के साथ प्रमुख समस्या यह है कि हीप में केवल दो महत्वपूर्ण विशेषताएं हैं: आधार, या वर्चुअल मेमोरी स्पेस में हीप की शुरुआत; और लंबाई, या इसका आकार। हीप को अपनी पूरी लंबाई भरने के लिए पर्याप्त सिस्टम मेमोरी की आवश्यकता होती है, और इसका आधार कभी नहीं बदल सकता। इस प्रकार, अप्रयुक्त मेमोरी का कोई भी बड़ा क्षेत्र बर्बाद हो जाता है। ढेर इस स्थिति में फंस सकता है यदि ढेर के अंत में एक छोटा सा इस्तेमाल किया गया खंड मौजूद है, जो किसी भी पते की जगह को बर्बाद कर सकता है। आलसी मेमोरी आवंटन योजनाओं पर, जैसे कि अक्सर लिनक्स ऑपरेटिंग सिस्टम में पाए जाते हैं, एक बड़ा हीप अनिवार्य रूप से समकक्ष सिस्टम मेमोरी को आरक्षित नहीं करता है; यह केवल पहली बार लिखने के समय ही ऐसा करेगा (गैर-मैप किए गए मेमोरी पेज शून्य पर लौटते हैं)। इसकी ग्रैन्युलैरिटी पृष्ठ आकार पर निर्भर करती है।
dlmalloc और ptmalloc
डग ली ने सार्वजनिक डोमेन dlmalloc (Doug Lea's malloc) को एक सामान्य-उद्देश्य आवंटक के रूप में विकसित किया है, जिसकी शुरुआत 1987 में हुई थी। GNU C लाइब्रेरी (glibc) वोल्फ्राम ग्लोगर के ptmalloc (pthreads malloc) से ली गई है, जो थ्रेडिंग से संबंधित dlmalloc का एक कांटा है। सुधार।[20][21][22] नवंबर 2019 तक, dlmalloc का नवीनतम संस्करण अगस्त 2012 से संस्करण 2.8.6 है।[23] dlmalloc एक सीमा टैग आवंटक है। हीप मेमोरी पर मेमोरी को चंक्स के रूप में आवंटित किया जाता है, एक 8-बाइट डेटा संरचना संरेखण डेटा संरचना जिसमें एक हेडर और प्रयोग करने योग्य मेमोरी होती है। आवंटित मेमोरी में चंक के आकार और उपयोग के झंडे (डोप वेक्टर के समान) के लिए 8- या 16-बाइट ओवरहेड होता है। अनाबंटित चंक्स उपयोग करने योग्य स्थान क्षेत्र में अन्य फ्री चंक्स के लिए पॉइंटर्स को भी स्टोर करते हैं, जिससे 32-बिट सिस्टम पर न्यूनतम चंक आकार 16 बाइट्स और 64-बिट सिस्टम पर 24/32 (संरेखण पर निर्भर करता है) बाइट्स बनते हैं।[21][23]: 2.8.6, Minimum allocated size असंबद्ध मेमोरी को समान आकार के बिन (कम्प्यूटेशनल ज्यामिति) में समूहीकृत किया जाता है, जिसे चंक्स की डबल-लिंक्ड सूची का उपयोग करके कार्यान्वित किया जाता है (चंक के अंदर असंबद्ध स्थान में संग्रहीत पॉइंटर्स के साथ)। डिब्बे आकार के अनुसार तीन वर्गों में क्रमबद्ध होते हैं:[21][23]: Overlaid data structures
- 256 बाइट्स (स्मॉलबिन अनुरोध) से नीचे के अनुरोधों के लिए, एक साधारण दो पावर बेस्ट फिट एलोकेटर का उपयोग किया जाता है। यदि उस बिन में कोई मुक्त ब्लॉक नहीं है, तो अगले उच्चतम बिन से एक ब्लॉक दो भागों में विभाजित हो जाता है।
- 256 बाइट्स या उससे ऊपर के अनुरोधों के लिए, लेकिन mmap थ्रेशोल्ड के नीचे, v2.8.0 के बाद से dlmalloc Trie#Bitwise try|in-place बिटवाइज़ ट्राई एल्गोरिथम (ट्रीबिन) का उपयोग करें। यदि अनुरोध को पूरा करने के लिए कोई खाली स्थान नहीं बचा है, तो dlmalloc ढेर के आकार को बढ़ाने की कोशिश करता है, आमतौर पर sbrk सिस्टम कॉल के माध्यम से। यह सुविधा ptmalloc (v2.7.x से) बनने के बाद पेश की गई थी, और इसके परिणामस्वरूप यह glibc का हिस्सा नहीं है, जो पुराने सबसे फिट आवंटक को विरासत में मिला है।
- एमएमएपी थ्रेसहोल्ड (लार्जबिन अनुरोध) से ऊपर के अनुरोधों के लिए, मेमोरी हमेशा एमएमएपी सिस्टम कॉल का उपयोग करके आवंटित की जाती है। सीमा आमतौर पर 256 केबी होती है।[24] एमएमएपी विधि बड़े बफ़र्स के साथ उनकी समाप्ति के बाद अंत में एक छोटे से आवंटन को फंसाने की समस्या को टालती है, लेकिन हमेशा मेमोरी के एक पूरे पृष्ठ (कंप्यूटर मेमोरी) को आवंटित करती है, जो कई आर्किटेक्चर पर आकार में 4096 बाइट्स है।[25]
गेम डेवलपर एड्रियन स्टोन का तर्क है कि dlmalloc
, एक सीमा-टैग आवंटक के रूप में, कंसोल सिस्टम के लिए अमित्र है जिसमें वर्चुअल मेमोरी है लेकिन मांग पेजिंग नहीं है। ऐसा इसलिए है क्योंकि इसके पूल-सिकुड़ते और बढ़ते कॉलबैक (सिसालोक/सिस्ट्रिम) का उपयोग वर्चुअल मेमोरी के अलग-अलग पेजों को आवंटित करने और कमिट करने के लिए नहीं किया जा सकता है। डिमांड पेजिंग के अभाव में विखंडन एक बड़ी चिंता बन जाता है।[26]
FreeBSD's और NetBSD's jemalloc
FreeBSD 7.0 और NetBSD 5.0 के बाद से, पुराना malloc
कार्यान्वयन (Poul-Henning Kamp द्वारा phkmalloc) को जेसन इवांस द्वारा लिखित jemalloc द्वारा प्रतिस्थापित किया गया था। इसका मुख्य कारण मल्टीथ्रेडिंग के मामले में phkmalloc की मापनीयता की कमी थी। लॉक विवाद से बचने के लिए, जेमलोक प्रत्येक केंद्रीय प्रसंस्करण इकाई के लिए अलग-अलग एरेनास का उपयोग करता है। मल्टीथ्रेडिंग एप्लिकेशन में प्रति सेकंड आवंटन की संख्या को मापने वाले प्रयोगों से पता चला है कि यह इसे थ्रेड्स की संख्या के साथ रैखिक रूप से स्केल करता है, जबकि phkmalloc और dlmalloc दोनों के लिए प्रदर्शन थ्रेड्स की संख्या के व्युत्क्रमानुपाती था।[27]
ओपनबीएसडी का मॉलोक
OpenBSD का कार्यान्वयन malloc
समारोह एमएमएपी का उपयोग करता है। एक पृष्ठ से बड़े आकार के अनुरोधों के लिए, संपूर्ण आवंटन का उपयोग करके पुनर्प्राप्त किया जाता है mmap
; द्वारा अनुरक्षित मेमोरी पूल से छोटे आकार निर्दिष्ट किए जाते हैं malloc
कई बकेट पेजों के भीतर, साथ ही आवंटित भी mmap
.[28][better source needed] एक कॉल पर free
, मेमोरी को रिलीज़ किया जाता है और प्रोसेस पता स्थान का उपयोग करके अनमैप किया जाता है munmap
. इस प्रणाली को ओपनबीएसडी के हिस्से के रूप में कार्यान्वित एड्रेस स्पेस लेआउट रैंडमाइजेशन और गैप पेज सुविधाओं का लाभ उठाकर सुरक्षा में सुधार करने के लिए डिज़ाइन किया गया है। mmap
सिस्टम कॉल, और उपयोग-बाद-मुक्त बग का पता लगाने के लिए- चूंकि एक बड़ी मेमोरी आवंटन मुक्त होने के बाद पूरी तरह से मैप नहीं किया गया है, आगे के उपयोग से विभाजन की गलती और कार्यक्रम की समाप्ति का कारण बनता है।
होर्ड मॉलोक
होर्ड एक एलोकेटर है जिसका लक्ष्य स्केलेबल मेमोरी आवंटन प्रदर्शन है। OpenBSD के संभाजक की तरह, होर्ड उपयोग करता है mmap
विशेष रूप से, लेकिन सुपरब्लॉक कहे जाने वाले 64 किलोबाइट के टुकड़ों में मेमोरी का प्रबंधन करता है। होर्ड के हीप को तार्किक रूप से एक ग्लोबल हीप और कई प्रति-प्रोसेसर हीप में विभाजित किया गया है। इसके अलावा, एक थ्रेड-लोकल कैश है जो सीमित संख्या में सुपरब्लॉक रख सकता है। स्थानीय प्रति-थ्रेड या प्रति-प्रोसेसर हीप पर केवल सुपरब्लॉक से आवंटित करके, और ज्यादातर खाली सुपरब्लॉक को ग्लोबल हीप में ले जाकर अन्य प्रोसेसर द्वारा पुन: उपयोग किया जा सकता है, थ्रेड्स की संख्या के साथ रैखिक मापनीयता प्राप्त करते समय होर्ड विखंडन को कम रखता है .[29]
मिमललोक
प्रदर्शन पर ध्यान देने के साथ माइक्रोसॉफ्ट रिसर्च से एक खुला स्त्रोत | ओपन-सोर्स कॉम्पैक्ट सामान्य-उद्देश्य मेमोरी एलोकेटर।[30] पुस्तकालय कोड की लगभग 11,000 पंक्तियाँ हैं।
थ्रेड-कैशिंग मॉलोक (tcmalloc)
छोटे आवंटन के लिए प्रत्येक थ्रेड में थ्रेड-लोकल स्टोरेज होता है। बड़े आवंटन के लिए mmap या sbrk का उपयोग किया जा सकता है। TCMalloc, Google द्वारा विकसित एक malloc,[31] मृत धागे के स्थानीय भंडारण के लिए कचरा संग्रह है। TCMalloc को बहुप्रचारित कार्यक्रमों के लिए glibc के ptmalloc से दुगने से भी अधिक तेज़ माना जाता है।[32][33]
इन-कर्नेल
ऑपरेटिंग सिस्टम कर्नेल (कंप्यूटर साइंस) को एप्लिकेशन प्रोग्राम की तरह ही मेमोरी आवंटित करने की आवश्यकता होती है। का कार्यान्वयन malloc
तथापि, कर्नेल के भीतर अक्सर सी पुस्तकालयों द्वारा उपयोग किए जाने वाले कार्यान्वयन से काफी भिन्न होता है। उदाहरण के लिए, मेमोरी बफ़र्स को प्रत्यक्ष मेमोरी एक्सेस द्वारा लगाए गए विशेष प्रतिबंधों के अनुरूप होने की आवश्यकता हो सकती है, या मेमोरी आवंटन फ़ंक्शन को इंटरप्ट संदर्भ से कॉल किया जा सकता है।[34] यह एक की आवश्यकता है malloc
कार्यान्वयन ऑपरेटिंग सिस्टम कर्नेल के आभासी मेमोरी सबसिस्टम के साथ कसकर एकीकृत है।
मॉलोक ओवरराइडिंग
क्योंकि malloc
और उसके रिश्तेदार किसी कार्यक्रम के प्रदर्शन पर गहरा प्रभाव डाल सकते हैं, एप्लिकेशन के आवंटन पैटर्न के लिए अनुकूलित किए गए कस्टम कार्यान्वयन द्वारा किसी विशिष्ट एप्लिकेशन के कार्यों को ओवरराइड करना असामान्य नहीं है। सी मानक ऐसा करने का कोई तरीका प्रदान नहीं करता है, लेकिन ऑपरेटिंग सिस्टम ने डायनेमिक लिंकिंग का फायदा उठाकर ऐसा करने के कई तरीके खोजे हैं। प्रतीकों को ओवरराइड करने के लिए एक तरीका केवल एक अलग पुस्तकालय में लिंक करना है। एक अन्य, UNIX System V#SVR3|Unix System V.3 द्वारा नियोजित, बनाना है malloc
और free
फ़ंक्शन पॉइंटर्स जो एक एप्लिकेशन कस्टम प्रकार्य पर रीसेट कर सकता है।[35]
POSIX-जैसी प्रणालियों पर सबसे आम रूप पर्यावरण चर LD_PRELOAD को आवंटक के पथ के साथ सेट करना है, ताकि डायनेमिक लिंकर libc कार्यान्वयन के बजाय malloc/calloc/free के उस संस्करण का उपयोग करे।
आवंटन आकार सीमा
सबसे बड़ा संभव मेमोरी ब्लॉक malloc
आवंटित कर सकते हैं मेजबान सिस्टम पर निर्भर करता है, विशेष रूप से भौतिक स्मृति का आकार और ऑपरेटिंग सिस्टम कार्यान्वयन।
सैद्धांतिक रूप से, सबसे बड़ी संख्या वह अधिकतम मान होना चाहिए जिसे a में रखा जा सकता है size_t
प्रकार, जो एक कार्यान्वयन-निर्भर अहस्ताक्षरित पूर्णांक है जो स्मृति के क्षेत्र के आकार का प्रतिनिधित्व करता है। C99 मानक में और बाद में, यह के रूप में उपलब्ध है SIZE_MAX
से लगातार <stdint.h>
. तथापि इसकी गारंटी नहीं है ISO C, यह आमतौर पर है 2^(CHAR_BIT * sizeof(size_t)) - 1
.
ग्लिबैक सिस्टम पर, सबसे बड़ा संभावित मेमोरी ब्लॉक malloc
आवंटित कर सकते हैं केवल इस आकार का आधा है, अर्थात् 2^(CHAR_BIT * sizeof(ptrdiff_t) - 1) - 1
.[36]
एक्सटेंशन और विकल्प
सी लाइब्रेरी कार्यान्वयन विभिन्न ऑपरेटिंग सिस्टम और कंपाइलर्स के साथ मानक के विकल्प और एक्सटेंशन के साथ आ सकता है malloc
इंटरफेस। इनमें से उल्लेखनीय है:
alloca
, जो कॉल स्टैक पर बाइट्स की अनुरोधित संख्या आवंटित करता है। कोई संबंधित डीलोकेशन फ़ंक्शन मौजूद नहीं है, क्योंकि आमतौर पर कॉलिंग फ़ंक्शन के वापस आते ही मेमोरी को हटा दिया जाता है।alloca
UNIX/32V|32/V (1978) से ही यूनिक्स सिस्टम पर मौजूद था, लेकिन इसका उपयोग कुछ (जैसे, एम्बेडेड) संदर्भों में समस्याग्रस्त हो सकता है।[37] जबकि कई कंपाइलरों द्वारा समर्थित है, यह एएनएसआई सी | एएनएसआई-सी मानक का हिस्सा नहीं है और इसलिए हमेशा पोर्टेबल नहीं हो सकता है। इससे मामूली प्रदर्शन समस्याएं भी हो सकती हैं: यह चर-आकार के स्टैक फ़्रेमों की ओर ले जाती है, ताकि दोनों कॉल स्टैक#STACK-POINTER को प्रबंधित करने की आवश्यकता हो (निश्चित आकार के स्टैक फ़्रेमों के साथ, इनमें से एक बेमानी है)।[38] बड़े आवंटन से स्टैक ओवरफ़्लो के कारण अपरिभाषित व्यवहार का जोखिम भी बढ़ सकता है।[39] C99 ने वैकल्पिक ढेर आवंटन तंत्र के रूप में चर-लंबाई सरणियों की पेशकश की – हालाँकि, इस सुविधा को बाद के C11 (C मानक संशोधन) मानक में वैकल्पिक कर दिया गया था।- POSIX एक फ़ंक्शन को परिभाषित करता है
posix_memalign
जो कॉलर-निर्दिष्ट संरेखण के साथ मेमोरी आवंटित करता है। इसका आवंटन विलोपित किया गया हैfree
,[40] इसलिए कार्यान्वयन को आमतौर पर मॉलोक लाइब्रेरी का हिस्सा होना चाहिए।
यह भी देखें
- बफ़र अधिकता
- मेमोरी डीबगर
- स्मृति सुरक्षा
- पेज (कंप्यूटर मेमोरी)
- चर-लंबाई सरणी
संदर्भ
- ↑ 1.0 1.1 7.20.3 Memory management functions (PDF). p. 313.
{{cite book}}
:|work=
ignored (help) - ↑ Summit, Steve. "Chapter 11: Memory Allocation". C Programming Notes. Retrieved 2020-07-11.
- ↑ "aligned_alloc(3) - Linux man page".
- ↑ Stroustrup, Bjarne (2008). Programming: Principles and Practice Using C++. Addison Wesley. p. 1009. ISBN 978-0-321-54372-1.
- ↑ "gcc manual". gnu.org. Retrieved 2008-12-14.
- ↑ Brian W. Kernighan, Dennis M. Ritchie, The C Programming Language, Prentice-Hall, 1978; Section 7.9 (page 156) describes
calloc
andcfree
, and Section 8.7 (page 173) describes an implementation foralloc
andfree
. - ↑ Version 6 Unix Programmer's Manual –
- ↑ Version 7 Unix Programmer's Manual –
- ↑ Anonymous, Unix Programmer's Manual, Vol. 1, Holt Rinehart and Winston, 1983 (copyright held by Bell Telephone Laboratories, 1983, 1979); The
man
page formalloc
etc. is given on page 275. - ↑ FreeBSD Library Functions Manual –
- ↑ Linux Programmer's Manual – Library Functions –
- ↑ Cite error: Invalid
<ref>
tag; no text was provided for refs namedCprog_malloc
- ↑ "comp.lang.c FAQ list · Question 7.7b". C-FAQ. Retrieved 2007-03-09.
- ↑ Reek, Kenneth (1997-08-04). Pointers on C (in English) (1 ed.). Pearson. ISBN 9780673999863.
- ↑ "MEM04-C. Beware of zero-length allocations - SEI CERT C Coding Standard - Confluence". wiki.sei.cmu.edu.
- ↑ "POSIX.1-2017: malloc". pubs.opengroup.org. Retrieved 2019-11-29.
- ↑ Awakened (2019-10-02). "How a double-free bug in WhatsApp turns to RCE". Retrieved 2019-11-29.
- ↑ Felker, Rich [@RichFelker] (2019-10-03). "Wow. The WhatsApp RCE was the wrong behavior for realloc(p,0) so many implementations insist on" (Tweet). Retrieved 2022-08-06 – via Twitter.
- ↑ Alexandrescu, Andrei (2001). Modern C++ Design: Generic Programming and Design Patterns Applied. Addison-Wesley. p. 78.
- ↑ "Wolfram Gloger's malloc homepage". malloc.de. Retrieved 2018-04-01.
- ↑ 21.0 21.1 21.2 Kaempf, Michel (2001). "Vudo malloc tricks". Phrack (57): 8. Archived from the original on 2009-01-22. Retrieved 2009-04-29.
- ↑ "Glibc: Malloc Internals". sourceware.org Trac. Retrieved 2019-12-01.
- ↑ 23.0 23.1 23.2 Lee, Doug. "A Memory Allocator". Retrieved 2019-12-01. HTTP for Source Code
- ↑ "Malloc Tunable Parameters". GNU. Retrieved 2009-05-02.
- ↑ Sanderson, Bruce (2004-12-12). "RAM, Virtual Memory, Pagefile and all that stuff". Microsoft Help and Support.
- ↑ Stone, Adrian. "The Hole That dlmalloc Can't Fill". Game Angst. Retrieved 2019-12-01.
- ↑ Evans, Jason (2006-04-16). "A Scalable Concurrent malloc(3) Implementation for FreeBSD" (PDF). Retrieved 2012-03-18.
- ↑ "libc/stdlib/malloc.c". BSD Cross Reference, OpenBSD src/lib/.
- ↑ Berger, E. D.; McKinley, K. S.; Blumofe, R. D.; Wilson, P. R. (November 2000). Hoard: A Scalable Memory Allocator for Multithreaded Applications (PDF). ASPLOS-IX. Proceedings of the ninth international conference on Architectural support for programming languages and operating systems. pp. 117–128. CiteSeerX 10.1.1.1.4174. doi:10.1145/378993.379232. ISBN 1-58113-317-0.
- ↑ Microsoft releases optimized malloc() as open source - Slashdot
- ↑ TCMalloc homepage
- ↑ Ghemawat, Sanjay; Menage, Paul; TCMalloc : Thread-Caching Malloc
- ↑ Callaghan, Mark (2009-01-18). "High Availability MySQL: Double sysbench throughput with TCMalloc". Mysqlha.blogspot.com. Retrieved 2011-09-18.
- ↑ "kmalloc()/kfree() include/linux/slab.h". People.netfilter.org. Retrieved 2011-09-18.
- ↑ Levine, John R. (2000) [October 1999]. "Chapter 9: Shared libraries". Linkers and Loaders. The Morgan Kaufmann Series in Software Engineering and Programming (1 ed.). San Francisco, USA: Morgan Kaufmann. ISBN 1-55860-496-0. OCLC 42413382. Archived from the original on 2012-12-05. Retrieved 2020-01-12. Code: [1][2] Errata: [3]
- ↑ "malloc: make malloc fail with requests larger than PTRDIFF_MAX". Sourceware Bugzilla. 2019-04-18. Retrieved 2020-07-30.
- ↑ "Why is the use of alloca() not considered good practice?". stackoverflow.com. Retrieved 2016-01-05.
- ↑ Amarasinghe, Saman; Leiserson, Charles (2010). "6.172 Performance Engineering of Software Systems, Lecture 10". MIT OpenCourseWare. Massachusetts Institute of Technology. Archived from the original on 2015-06-22. Retrieved 2015-01-27.
- ↑ "alloca(3) - Linux manual page". man7.org. Retrieved 2016-01-05.
- ↑ The Single UNIX Specification, Version 4 from The Open Group – System Interfaces Reference,
बाहरी संबंध
- Definition of malloc in IEEE Std 1003.1 standard
- Lea, Doug; The design of the basis of the glibc allocator
- Gloger, Wolfram; The ptmalloc homepage
- Berger, Emery; The Hoard homepage
- Douglas, Niall; The nedmalloc homepage
- Evans, Jason; The jemalloc homepage
- Google; The tcmalloc homepage
- Simple Memory Allocation Algorithms on OSDEV Community
- Michael, Maged M.; Scalable Lock-Free Dynamic Memory Allocation
- Bartlett, Jonathan; Inside memory management – The choices, tradeoffs, and implementations of dynamic allocation
- Memory Reduction (GNOME) wiki page with much information about fixing malloc
- C99 standard draft, including TC1/TC2/TC3
- Some useful references about C
- ISO/IEC 9899 – Programming languages – C
- Understanding glibc malloc