क्या करने में अंतर है:
ptr = (char **) malloc (MAXELEMS * sizeof(char *));
या:
ptr = (char **) calloc (MAXELEMS, sizeof(char*));
जब मॉलॉक या इसके विपरीत कॉलोक का उपयोग करना एक अच्छा विचार है?
ptr = calloc(MAXELEMS, sizeof(*ptr));
क्या करने में अंतर है:
ptr = (char **) malloc (MAXELEMS * sizeof(char *));
या:
ptr = (char **) calloc (MAXELEMS, sizeof(char*));
जब मॉलॉक या इसके विपरीत कॉलोक का उपयोग करना एक अच्छा विचार है?
ptr = calloc(MAXELEMS, sizeof(*ptr));
जवाबों:
calloc()
आपको शून्य-आरंभिक बफ़र malloc()
देता है , जबकि स्मृति को असिंचित छोड़ देता है।
बड़े आवंटन के लिए, calloc
मुख्यधारा के OS के तहत अधिकांश कार्यान्वयन OS से ज्ञात-शून्य पृष्ठ (जैसे POSIX mmap(MAP_ANONYMOUS)
या विंडोज के माध्यम से VirtualAlloc
) प्राप्त करेंगे, इसलिए उन्हें उपयोगकर्ता-स्थान में लिखने की आवश्यकता नहीं है। यह सामान्य malloc
है और साथ ही ओएस से अधिक पृष्ठ कैसे मिलते हैं; calloc
बस ओएस की गारंटी का फायदा उठाता है।
इसका मतलब यह है कि calloc
मेमोरी अभी भी "साफ" और आलसी-आवंटित हो सकती है, और सिस्टम-आधारित साझा भौतिक पृष्ठ पर शून्य से कॉपी-ऑन-राइट मैप की जा सकती है। (वर्चुअल मेमोरी वाले सिस्टम को मान लें।)
कुछ कंपाइलर भी आपके लिए कॉलोक में मॉलॉक + मेमसेट (0) को ऑप्टिमाइज़ कर सकते हैं, लेकिन आपको स्पष्ट रूप से कॉलोक का उपयोग करना चाहिए यदि आप मेमोरी को पढ़ना चाहते हैं 0
।
यदि आप इसे लिखने से पहले कभी मेमोरी पढ़ने नहीं जा रहे हैं, malloc
तो इसका उपयोग करें (संभावित रूप से) आपको ओएस से नए पृष्ठ प्राप्त करने के बजाय इसकी आंतरिक मुक्त सूची से गंदी मेमोरी दे सकता है। (या एक छोटे से आवंटन के लिए मुफ्त सूची पर मेमोरी के ब्लॉक को शून्य करने के बजाय)।
यदि कोई OS नहीं है, तो एंबेडेड क्रियान्वयन calloc
इसे calloc
शून्य मेमोरी तक छोड़ सकता है , या यह एक फैंसी बहु-उपयोगकर्ता OS नहीं है जो प्रक्रियाओं के बीच सूचना लीक को रोकने के लिए पृष्ठों को शून्य करता है।
एम्बेडेड लिनक्स पर, मॉलोक mmap(MAP_UNINITIALIZED|MAP_ANONYMOUS)
, जो केवल कुछ एम्बेडेड कर्नेल के लिए सक्षम है, क्योंकि यह एक बहु-उपयोगकर्ता प्रणाली पर असुरक्षित है।
calloc
जरूरी नहीं कि अधिक महंगा है, क्योंकि ओएस इसे गति देने के लिए कुछ चालें कर सकता है। मुझे पता है कि FreeBSD, जब इसे किसी भी निष्क्रिय सीपीयू समय मिलता है, तो इसका उपयोग एक सरल प्रक्रिया को चलाने के लिए होता है जो बस स्मृति के ब्लॉक किए गए ब्लॉकों को चारों ओर चला जाता है और ब्लॉक करता है और इस प्रकार एक ध्वज के साथ प्रक्रियाओं को चिह्नित करता है। इसलिए जब आप ऐसा करते हैं calloc
, तो यह पहले ऐसे पूर्व-शून्य ब्लॉकों में से एक को खोजने की कोशिश करता है और बस आपको देता है - और सबसे अधिक संभावना है कि यह एक मिल जाएगा।
एक कम ज्ञात अंतर यह है कि लिनक्स की तरह आशावादी मेमोरी आवंटन के साथ ऑपरेटिंग सिस्टम में, पॉइंटर द्वारा लौटाया malloc
गया वास्तविक मेमोरी द्वारा समर्थित नहीं है जब तक कि प्रोग्राम वास्तव में इसे छूता नहीं है।
calloc
वास्तव में मेमोरी को छूता है (यह उस पर जीरो लिखता है) और इस तरह आपको यकीन होगा कि ओएस वास्तविक रैम (या स्वैप) के साथ आवंटन का समर्थन कर रहा है। यह भी यही कारण है कि यह मॉलोक की तुलना में धीमा है (न केवल इसे शून्य करना है, ओएस को संभवतः अन्य प्रक्रियाओं को स्वैप करके एक उपयुक्त मेमोरी क्षेत्र भी खोजना होगा)
उदाहरण के लिए देखें मलोक के व्यवहार के बारे में अधिक चर्चा के लिए यह एसओ प्रश्न
calloc
शून्य लिखने की आवश्यकता नहीं है। यदि आबंटित ब्लॉक में ऑपरेटिंग सिस्टम द्वारा प्रदान किए गए अधिकतर नए शून्य पृष्ठ हैं, तो यह उन लोगों को अछूता छोड़ सकता है। इस कोर्स के calloc
शीर्ष पर एक सामान्य लाइब्रेरी फ़ंक्शन के बजाय ऑपरेटिंग सिस्टम को ट्यून करने की आवश्यकता है malloc
। या, एक कार्यान्वयनकर्ता calloc
शून्य के मुकाबले प्रत्येक शब्द की तुलना शून्य से पहले कर सकता है। यह किसी भी समय नहीं बचा होगा, लेकिन यह नए पृष्ठों को गंदा करने से बचाएगा।
dlmalloc
कार्यान्वयन को छोड़ दें memset
यदि चंक को mmap
नए अनाम पृष्ठों (या समतुल्य) के माध्यम से प्राप्त किया गया था । आमतौर पर इस तरह के आवंटन का उपयोग बड़े पैमाने पर विखंडन के लिए किया जाता है, 256k या तो शुरू होता है। मैं किसी भी कार्यान्वयन के बारे में नहीं जानता जो शून्य के खिलाफ तुलना लिखने से पहले शून्य को अपने से अलग करता है।
omalloc
भी छोड़ देता है memset
; calloc
किसी भी ऐसे पृष्ठ को छूने की आवश्यकता नहीं है जो पहले से ही एप्लिकेशन (पेज कैश) द्वारा उपयोग नहीं किया जाता है। हालांकि, अत्यंत आदिम calloc
कार्यान्वयन अलग हैं।
एक अक्सर-अनदेखी लाभ calloc
यह है कि (अनुरूप कार्यान्वयन) यह पूर्णांक अतिप्रवाह कमजोरियों के खिलाफ आपकी रक्षा करने में मदद करेगा। की तुलना करें:
size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);
बनाम
size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);
पूर्व एक छोटे से आवंटन और बाद में बफर overflows में परिणाम सकता है, अगर count
से अधिक है SIZE_MAX/sizeof *bar
। उत्तरार्द्ध इस मामले में स्वचालित रूप से विफल हो जाएगा क्योंकि एक वस्तु जो बड़ी नहीं बनाई जा सकती है।
बेशक आपको गैर-अनुरूप कार्यान्वयन के लिए तलाश में रहना पड़ सकता है जो बस अतिप्रवाह की संभावना को अनदेखा करते हैं ... यदि यह आपके द्वारा लक्षित प्लेटफार्मों पर चिंता का विषय है, तो आपको वैसे भी अतिप्रवाह के लिए एक मैनुअल परीक्षण करना होगा।
char
है नहीं एक अतिप्रवाह बल्कि एक कार्यान्वयन-परिभाषित रूपांतरण जब एक में परिणाम वापस बताए char
वस्तु।
size_t
64-बिट है तो कोई समस्या नहीं है", यह सोच का एक त्रुटिपूर्ण तरीका है जो सुरक्षा बगों को जन्म देने वाला है। size_t
एक अमूर्त प्रकार है जो आकारों का प्रतिनिधित्व करता है, और 32-बिट संख्या और एक size_t
( एक नोट के मनमाने ढंग से उत्पाद के बारे में सोचने का कोई कारण नहीं है : sizeof *bar
सिद्धांत रूप में 64-बिट सी कार्यान्वयन पर 2 ^ 32 से अधिक हो सकता है!) में फिट बैठता है size_t
।
प्रलेखन कॉलॉक को मॉलोक की तरह दिखता है, जो स्मृति को शून्य-प्रारंभिक करता है; यह प्राथमिक अंतर नहीं है! कॉलोक का विचार स्मृति आवंटन के लिए कॉपी-ऑन-राइट शब्दार्थ को निरस्त करना है। जब आप कॉलॉक के साथ मेमोरी आवंटित करते हैं तो यह सभी मैप्स को उसी भौतिक पृष्ठ पर भेज देता है जिसे शून्य पर आरम्भ किया जाता है। जब आवंटित मेमोरी के किसी भी पृष्ठ को भौतिक पृष्ठ में लिखा जाता है तो उसे आवंटित किया जाता है। यह अक्सर हैश हैश टेबल बनाने के लिए उपयोग किया जाता है, उदाहरण के लिए चूंकि हैश के हिस्से जो खाली हैं वे किसी भी अतिरिक्त मेमोरी (पेज) द्वारा समर्थित नहीं हैं; वे खुशी से एकल शून्य-प्रारंभिक पृष्ठ पर इंगित करते हैं, जिसे प्रक्रियाओं के बीच भी साझा किया जा सकता है।
किसी भी वर्चुअल पते पर किसी पृष्ठ पर मैप किया जाता है, यदि वह पृष्ठ शून्य-पृष्ठ है, तो एक अन्य भौतिक पृष्ठ आवंटित किया जाता है, शून्य पृष्ठ की प्रतिलिपि बनाई जाती है और नियंत्रण प्रवाह क्लाइंट प्रक्रिया में वापस आ जाता है। यह उसी तरह से काम करता है जैसे कि मेमोरी मैप्ड फाइल्स, वर्चुअल मेमोरी आदि काम करते हैं। यह पेजिंग का उपयोग करता है।
यहाँ विषय के बारे में एक अनुकूलन कहानी है: http://blogs.fau.de/hager/2007/05/08/benchmarking-fun-with-calloc-and-zero-pages/
आबंटित मेमोरी ब्लॉक के आकार में कोई अंतर नहीं है। calloc
सिर्फ भौतिक ऑल-जीरो-बिट्स पैटर्न के साथ मेमोरी ब्लॉक भरता है। व्यवहार में अक्सर यह माना जाता है कि आवंटित मेमोरी ब्लॉक में स्थित ऑब्जेक्ट्स में calloc
इनिटिलियल वैल्यू होती है जैसे कि उन्हें शाब्दिक रूप से इनिशियलाइज़ किया गया था 0
, यानी पूर्णांकों का मान 0
, फ्लोटिंग-पॉइंट वैरिएबल - वैल्यू ऑफ़ 0.0
, पॉइंटर्स - उपयुक्त अशक्त-पॉइंटर वैल्यू होना चाहिए , और इसी तरह।
पांडित्य के दृष्टिकोण से, हालांकि calloc
(और साथ ही memset(..., 0, ...)
) केवल प्रकार की वस्तुओं को ठीक से ज़ीरो (प्रारंभिक) के साथ निर्धारित करने की गारंटी है unsigned char
। बाकी सब कुछ ठीक से प्रारंभिक होने की गारंटी नहीं है और इसमें तथाकथित ट्रैप प्रतिनिधित्व शामिल हो सकता है , जो अपरिभाषित व्यवहार का कारण बनता है। दूसरे शब्दों में, unsigned char
उपरोक्त सभी-शून्य-बिट्स पैटरम के अलावा किसी भी प्रकार के लिए एक अवैध मूल्य, ट्रैप प्रतिनिधित्व का प्रतिनिधित्व कर सकता है।
बाद में, तकनीकी कोरिगेंडा में C99 मानक में से एक में, सभी पूर्णांक प्रकारों के लिए व्यवहार को परिभाषित किया गया था (जो समझ में आता है)। यानी औपचारिक रूप से, वर्तमान C भाषा में आप केवल calloc
(और memset(..., 0, ...)
) के साथ पूर्णांक प्रकारों को प्रारंभ कर सकते हैं । सामान्य मामले में किसी और चीज को इनिशियलाइज़ करने के लिए इसका इस्तेमाल करने से सी भाषा के दृष्टिकोण से अपरिभाषित व्यवहार होता है।
व्यवहार में, calloc
काम करता है, जैसा कि हम सभी जानते हैं :), लेकिन क्या आप इसका उपयोग करना चाहते हैं (ऊपर विचार करके) आप पर निर्भर है। मैं व्यक्तिगत रूप से इसे पूरी तरह से बचना पसंद करता हूं, malloc
इसके बजाय उपयोग करें और अपनी खुद की इनिशियलाइज़ेशन करें।
अंत में, एक अन्य महत्वपूर्ण विवरण यह है कि तत्वों की संख्या से तत्व आकार को गुणा करके, calloc
अंतिम ब्लॉक आकार की आंतरिक रूप से गणना करना आवश्यक है । ऐसा करते समय, calloc
संभव अंकगणित अतिप्रवाह के लिए देखना चाहिए। यदि असफल ब्लॉक आकार की सही गणना नहीं की जा सकती है तो यह असफल आवंटन (अशक्त सूचक) के परिणामस्वरूप होगा। इस बीच, आपका malloc
संस्करण अतिप्रवाह के लिए देखने का कोई प्रयास नहीं करता है। यह अतिप्रवाह होने पर कुछ "अप्रत्याशित" मात्रा में मेमोरी आवंटित करेगा।
memset(p, v, n * sizeof type);
एक समस्या है क्योंकि n * sizeof type
अतिप्रवाह हो सकता है। मुझे लगता है कि मैं for(i=0;i<n;i++) p[i]=v;
मजबूत कोड के लिए एक पाश का उपयोग करने की आवश्यकता होगी ।
n
तत्वों के साथ एक सरणी मौजूद है जहां एक तत्व का आकार है sizeof type
, तो n*sizeof type
अतिप्रवाह नहीं हो सकता है, क्योंकि किसी भी वस्तु का अधिकतम आकार इससे कम होना चाहिए SIZE_MAX
।
SIZE_MAX
, फिर भी यहाँ कोई सरणियाँ नहीं हैं। पॉइंटर से लौटाया calloc()
गया आवंटित मेमोरी की तुलना में अधिक हो सकता है SIZE_MAX
। कई प्रयोगों के लिए 2 आर्ग के उत्पाद सीमित करते हैं calloc()
करने के लिए SIZE_MAX
, अभी तक सी कल्पना है कि सीमा लागू नहीं है।
जॉर्ज हेगर के ब्लॉग पर कॉलोक () और शून्य पृष्ठों के साथ एक आलेख बेंचमार्किंग मज़ा
कॉलोक () का उपयोग करके मेमोरी आवंटित करते समय अनुरोध की गई मेमोरी को तुरंत आवंटित नहीं किया जाता है। इसके बजाय, सभी पृष्ठ जो मेमोरी ब्लॉक से संबंधित हैं, वे किसी एकल पृष्ठ से जुड़े होते हैं, जिसमें सभी MMU मैजिक (नीचे लिंक) होते हैं। यदि ऐसे पृष्ठ केवल पढ़े जाते हैं (जो बेंचमार्क के मूल संस्करण में सरणियों b, c और d के लिए सही था), तो डेटा एकल शून्य पृष्ठ से प्रदान किया जाता है, जो निश्चित रूप से - कैश में फिट बैठता है। मेमोरी-बाउंड लूप कर्नेल के लिए बहुत कुछ। यदि कोई पृष्ठ (कोई फर्क नहीं पड़ता) को लिखा जाता है, तो एक गलती होती है, "वास्तविक" पृष्ठ मैप किया जाता है और शून्य पृष्ठ को स्मृति में कॉपी किया जाता है। इसे कॉपी-ऑन-राइट कहा जाता है, एक प्रसिद्ध अनुकूलन दृष्टिकोण (जो मैंने अपने सी ++ व्याख्यान में कई बार सिखाया है)। उसके बाद,
calloc
आम तौर malloc+memset
पर 0 है
आमतौर पर malloc+memset
स्पष्ट रूप से उपयोग करना थोड़ा बेहतर होता है , खासकर जब आप कुछ ऐसा कर रहे हों:
ptr=malloc(sizeof(Item));
memset(ptr, 0, sizeof(Item));
यह बेहतर है क्योंकि sizeof(Item)
संकलन समय पर संकलक को पता है और संकलक ज्यादातर मामलों में इसे शून्य मेमोरी के लिए सर्वोत्तम संभव निर्देशों के साथ बदल देगा। दूसरी ओर यदि memset
हो रहा है calloc
, तो आवंटन का पैरामीटर आकार calloc
कोड में संकलित नहीं किया memset
जाता है और वास्तविक को अक्सर कहा जाता है, जिसमें आमतौर पर बाइट-बाइट करने के लिए कोड होता है, जो लंबे समय तक सीमा तक भरते हैं, चक्र से भरने के लिए। sizeof(long)
चंक्स में अप मेमोरी और अंत में बाइट-बाइट शेष स्थान को भरते हैं। यहां तक कि अगर आबंटक कुछ कॉल करने के लिए पर्याप्त स्मार्ट है, aligned_memset
तब भी यह एक सामान्य लूप होगा।
एक उल्लेखनीय अपवाद तब होगा जब आप मेमोरी के बहुत बड़े हिस्से (कुछ पॉवर_ऑफ_ट्वो किलोबाइट्स) का मॉलोक / कॉलोक कर रहे हों, जिसमें केस आवंटन सीधे कर्नेल से किया जा सकता है। जैसा कि ओएस कर्नेल आमतौर पर सुरक्षा कारणों से दूर की जाने वाली सभी मेमोरी को शून्य कर देते हैं, स्मार्ट पर्याप्त कॉलोक बस इसे अतिरिक्त शून्य के साथ वापस कर सकता है। फिर से - यदि आप कुछ ऐसा कर रहे हैं जिसे आप जानते हैं कि वह छोटा है, तो आप मॉलोक + मेस्सेट प्रदर्शन-वार के साथ बेहतर हो सकते हैं।
calloc()
धीमा है malloc()
: आकार के लिए गुणा। calloc()
जेनेरिक गुणन (यदि size_t
64 बिट्स बहुत महंगा 64 बिट्स * 64 बिट्स = 64 बिट्स ऑपरेशन है) का उपयोग करना आवश्यक है, जबकि मॉलॉक () में अक्सर एक संकलन समय स्थिर होगा।
struct foo { char a,b,c; };
। calloc
हमेशा malloc
+ से बेहतर है memset
, यदि आप हमेशा पूरे malloc
एड क्षेत्र को खाली करने जा रहे हैं । calloc
आकार * तत्वों में int अतिप्रवाह के लिए एक सावधान लेकिन कुशल जाँच है, भी।
अंतर 1:
malloc()
आमतौर पर मेमोरी ब्लॉक को आवंटित किया जाता है और यह आरंभिक मेमोरी सेगमेंट है।
calloc()
मेमोरी ब्लॉक को आवंटित करता है और सभी मेमोरी ब्लॉक को 0 में इनिशियलाइज़ करता है।
अंतर 2:
यदि आप malloc()
वाक्यविन्यास पर विचार करते हैं, तो यह केवल 1 तर्क लेगा। नीचे दिए गए उदाहरण पर विचार करें:
data_type ptr = (cast_type *)malloc( sizeof(data_type)*no_of_blocks );
Ex: यदि आप int प्रकार के लिए मेमोरी के 10 ब्लॉक आवंटित करना चाहते हैं,
int *ptr = (int *) malloc(sizeof(int) * 10 );
यदि आप calloc()
वाक्यविन्यास पर विचार करते हैं, तो यह 2 तर्क लेगा। नीचे दिए गए उदाहरण पर विचार करें:
data_type ptr = (cast_type *)calloc(no_of_blocks, (sizeof(data_type)));
Ex: यदि आप int प्रकार के लिए मेमोरी के 10 ब्लॉक आवंटित करना चाहते हैं और ZERO को सभी को प्रारंभ करें,
int *ptr = (int *) calloc(10, (sizeof(int)));
समानता:
दोनों malloc()
और calloc()
डिफ़ॉल्ट रूप से शून्य * वापस आ जाएगी अगर वे casted प्रकार नहीं कर रहे हैं।!
दो अंतर हैं।
सबसे पहले, तर्कों की संख्या में है। malloc()
एकल तर्क (बाइट्स में आवश्यक मेमोरी) लेता है, जबकि calloc()
दो तर्कों की आवश्यकता होती है।
दूसरे, आवंटित मेमोरी को malloc()
इनिशियलाइज़ नहीं करता है, जबकि calloc()
आवंटित मेमोरी को ज़ीरो को इनिशियलाइज़ करता है।
calloc()
एक स्मृति क्षेत्र आवंटित करता है, लंबाई इसके मापदंडों का उत्पाद होगी। calloc
ZERO के साथ मेमोरी को भरता है और पहले बाइट को पॉइंटर देता है। यदि यह पर्याप्त स्थान खोजने में विफल रहता है तो यह एक NULL
पॉइंटर लौटाता है ।सिंटेक्स: ptr_var=(cast_type *)calloc(no_of_blocks , size_of_each_block);
यानीptr_var=(type *)calloc(n,s);
malloc()
आवश्यक आकार की स्मृति का एक ब्लॉक आवंटित करता है और पहले बाइट के लिए एक संकेतक लौटाता है। यदि यह मेमोरी की आवश्यक राशि का पता लगाने में विफल रहता है तो यह अशक्त सूचक देता है।सिंटेक्स: समारोह, एक तर्क है, जो बाइट की संख्या आवंटित करने के लिए ले, जबकि समारोह तत्वों की संख्या जा रहा है एक दो तर्क लेता है, और अन्य बाइट की संख्या उन तत्वों में से प्रत्येक के लिए आवंटित करने के लिए किया जा रहा है। इसके अलावा, आवंटित स्थान को शून्य से आरंभ करता है , जबकि ऐसा नहीं करता है।ptr_var=(cast_type *)malloc(Size_in_bytes);
malloc()
calloc()
calloc()
malloc()
calloc()
समारोह है कि में घोषित किया जाता है <stdlib.h>
हैडर का लाभ होता की एक जोड़ी प्रदान करता है malloc()
कार्य करते हैं।
malloc()
और calloc()
सी मानक पुस्तकालय से कार्य हैं जो गतिशील मेमोरी आवंटन की अनुमति देते हैं, जिसका अर्थ है कि वे दोनों रनटाइम के दौरान मेमोरी आवंटन की अनुमति देते हैं।
उनके प्रोटोटाइप इस प्रकार हैं:
void *malloc( size_t n);
void *calloc( size_t n, size_t t)
दोनों के बीच मुख्य रूप से दो अंतर हैं:
व्यवहार: malloc()
एक मेमोरी ब्लॉक को आवंटित करता है, इसे शुरू किए बिना, और इस ब्लॉक से सामग्री को पढ़ने से कचरा मान उत्पन्न होगा। calloc()
दूसरी ओर, एक मेमोरी ब्लॉक आवंटित करता है और इसे शून्य पर आरंभीकृत करता है, और जाहिर है कि इस ब्लॉक की सामग्री को पढ़ने से शून्य हो जाएगा।
सिंटैक्स: malloc()
1 तर्क लेता है (आकार आवंटित किया जाना है), और calloc()
दो तर्क लेता है (आवंटित किए जाने वाले ब्लॉक की संख्या और प्रत्येक ब्लॉक का आकार)।
दोनों से वापसी का मान यदि सफल हो तो मेमोरी के आवंटित ब्लॉक के लिए एक संकेतक है। अन्यथा, NULL को स्मृति आबंटन विफलता का संकेत देते हुए लौटा दिया जाएगा।
उदाहरण:
int *arr;
// allocate memory for 10 integers with garbage values
arr = (int *)malloc(10 * sizeof(int));
// allocate memory for 10 integers and sets all of them to 0
arr = (int *)calloc(10, sizeof(int));
उसी कार्यक्षमता calloc()
का उपयोग करके प्राप्त किया जा सकता है malloc()
और memset()
:
// allocate memory for 10 integers with garbage values
arr= (int *)malloc(10 * sizeof(int));
// set all of them to 0
memset(arr, 0, 10 * sizeof(int));
ध्यान दें कि यह तेजी malloc()
से होने के calloc()
बाद से अधिमानतः उपयोग किया जाता है । यदि मानों को शून्य-प्रारंभिक करना है, तो calloc()
इसके बजाय उपयोग करें ।
एक अंतर जो अभी तक उल्लेख नहीं किया गया है: आकार सीमा
void *malloc(size_t size)
तक ही आवंटित किया जा सकता है SIZE_MAX
।
void *calloc(size_t nmemb, size_t size);
के बारे में आवंटित कर सकते हैं SIZE_MAX*SIZE_MAX
।
इस क्षमता का उपयोग अक्सर रैखिक पतों के साथ कई प्लेटफार्मों में नहीं किया जाता है। इस तरह की प्रणालियों के calloc()
साथ सीमा होती है nmemb * size <= SIZE_MAX
।
एक प्रकार के 512 बाइट्स पर विचार करें जिसे disk_sector
कोड कहा जाता है और कोड बहुत सारे सेक्टर का उपयोग करना चाहता है । यहां, कोड केवल SIZE_MAX/sizeof disk_sector
क्षेत्रों तक का उपयोग कर सकते हैं ।
size_t count = SIZE_MAX/sizeof disk_sector;
disk_sector *p = malloc(count * sizeof *p);
निम्नलिखित पर विचार करें जो एक और भी बड़े आवंटन की अनुमति देता है।
size_t count = something_in_the_range(SIZE_MAX/sizeof disk_sector + 1, SIZE_MAX)
disk_sector *p = calloc(count, sizeof *p);
अब अगर इस तरह की व्यवस्था इतने बड़े आवंटन की आपूर्ति कर सकती है तो यह एक और मामला है। अधिकांश आज नहीं करेंगे। फिर भी यह कई वर्षों के लिए हुआ है जब SIZE_MAX
65535 था। मूर के कानून को देखते हुए , यह संदेह है कि यह 2030 में कुछ मेमोरी मॉडल के साथ SIZE_MAX == 4294967295
और 100 जीबीटी में मेमोरी पूल के साथ होगा ।
size_t
से 32 बिट्स से बड़ा बना देगा । एकमात्र सवाल यह है कि क्या calloc
उन मूल्यों का उपयोग किया SIZE_MAX
जा सकता है जिनके उत्पाद से अधिक होने पर एक छोटे से आवंटन के लिए सूचक को वापस करने के बजाय शून्य उपज पर भरोसा किया जा सकता है।
calloc()
आवंटन से अधिक की अनुमति देता है SIZE_MAX
। यह 16-बिट के साथ अतीत में हुआ है size_t
और जैसे - जैसे स्मृति सस्ता होती जा रही है, मुझे लगता है कि कोई कारण नहीं कि यह सामान्य होने पर भी आगे नहीं बढ़ेगा ।
SIZE_MAX
। यह निश्चित रूप से आवश्यक नहीं है कि ऐसी कोई परिस्थिति हो जिसके तहत ऐसा आवंटन सफल हो सके; मुझे यकीन नहीं है कि यह सुनिश्चित करने से कोई विशेष लाभ है कि कार्यान्वयन जो इस तरह के आवंटन को संभाल नहीं सकते हैं, उन्हें वापस लौटना चाहिए NULL
(विशेषकर यह कि यह कुछ कार्यान्वयन के लिए सामान्य है कि malloc
रिटर्न पॉइंटर्स स्पेस में हैं जो अभी तक प्रतिबद्ध नहीं है और उपलब्ध नहीं हो सकता है जब कोड वास्तव में उपयोग करने की कोशिश करता है। यह)।
size_t
करेगा uint64_t
?
ब्लॉक की संख्या:
मॉलॉक ()
अनुरोधित मेमोरी के सिंगल ब्लॉक को असाइन करता है,
कॉलॉक () अनुरोधित मेमोरी के कई ब्लॉकों को असाइन करता है
प्रारंभ:
मॉलोक () - स्पष्ट नहीं है और आवंटित स्मृति को इनिशियलाइज़ करता है।
calloc () - आवंटित स्मृति को शून्य से आरंभ करता है।
गति:
मॉलोक () तेज है।
कॉलॉक () मॉलॉक () की तुलना में धीमा है।
तर्क और वाक्य रचना:
मॉलॉक () 1 तर्क लेता है:
बाइट्स
कॉलोक () 2 तर्क लेता है:
लंबाई
void *malloc(size_t bytes);
void *calloc(size_t length, size_t bytes);
स्मृति आबंटन
की क्षमता : मैलोक फ़ंक्शन उपलब्ध ढेर से वांछित 'आकार' की स्मृति प्रदान करता है।
कॉलोक फ़ंक्शन मेमोरी को असाइन करता है जो कि 'संख्या * आकार' के बराबर है।
नाम पर अर्थ:
नाम मॉलोक का अर्थ है "मेमोरी आवंटन"।
कॉलॉक नाम का अर्थ है "सन्निहित आवंटन"।
malloc
परिवार का परिणाम नहीं देते हैं