मॉलोक (0) का क्या मतलब है?


जवाबों:


121

विनिर्देशों के अनुसार, मॉलोक (0) या तो "अशक्त सूचक या एक अद्वितीय सूचक होगा जो सफलतापूर्वक मुक्त ()" में पारित किया जा सकता है।

यह मूल रूप से आपको कुछ भी आवंटित करने की अनुमति नहीं देता है, लेकिन फिर भी "कलाकार" चर को बिना किसी चिंता के मुफ्त () में कॉल करें। व्यावहारिक उद्देश्यों के लिए, ऐसा करना बहुत अधिक है:

artist = NULL;

51
व्यक्तिगत रूप से, मुझे लगता है कि NULL पर सेटिंग एक बेहतर क्रॉस-प्लेटफॉर्म रणनीति है, क्योंकि NULL पर इनपुट के रूप में ठीक काम करने के लिए मुफ्त () की गारंटी है।
रीड कोपसे

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

9
वास्तव में काश चश्मा कहेंगे "सुरक्षित रूप से realloc करने के लिए पारित कर दिया" के रूप में अच्छी तरह से
।-

1
@NSAddict "खाली संरचना जहां साइज़ोफ़ 0 पर वापस आएगी", कृपया एक उदाहरण प्रदान करें, एक भाषा एक्सटेंशन की तरह लगता है।
chux -

1
@hanshenrik कौन कहता है कि आप नहीं कर सकते हैं? realloc()आपको किसी भी वैध पॉइंटर को पास करने की अनुमति देता है malloc()। पर्याप्त होगा।
glglgl

51

C मानक (C17 7.22.3 / 1) कहता है:

यदि अनुरोधित स्थान का आकार शून्य है, तो व्यवहार को परिभाषित किया गया है: या तो एक नल सूचक वापस आ गया है, या व्यवहार ऐसा है जैसे आकार कुछ गैर-अक्षीय मान थे, सिवाय इसके कि किसी वस्तु तक पहुंचने के लिए दिए गए सूचक का उपयोग नहीं किया जाएगा।

तो, malloc(0)वापस आ सकता है NULLया एक वैध पॉइंटर हो सकता है जिसे डीरेफर नहीं किया जा सकता है । किसी भी मामले में, यह उस free()पर कॉल करने के लिए पूरी तरह से वैध है।

मुझे नहीं लगता कि उदाहरण के लिए एक लूप में कहा जाता है, और शून्य हो सकता है malloc(0)जब मामलों को छोड़कर, बहुत उपयोग किया है।malloc(n)n

लिंक में कोड को देखते हुए, मुझे विश्वास है कि लेखक को दो गलत धारणाएं थीं:

  • malloc(0)एक वैध पॉइंटर हमेशा देता है , और
  • free(0) बुरा है।

इसलिए, उन्होंने यह सुनिश्चित किया कि artistऔर अन्य चर हमेशा उनमें कुछ "वैध" मूल्य रखते थे। टिप्पणी के रूप में ज्यादा कहते हैं // these must always point at malloc'd data:।


10
तथ्य यह है कि यह कार्यान्वयन पर निर्भर है, यह कम या ज्यादा पूरी तरह से बेकार बना देता है - यह सी मानक के क्रैपीयर बिट्स में से एक है, और काफी कुछ मानक कॉमेट्टी (उदाहरण के लिए पीजे प्लॉगर) इसके बारे में विलाप कर चुके हैं।

10
मैं सहमत हूँ। यदि malloc(0)एक वैध पॉइंटर लौटाया जाता है, तो malloc()लौटने का NULLमतलब हमेशा "विफलता" होता है, और 0अब कोई विशेष मामला नहीं है, जो अधिक सुसंगत है।
आलोक सिंघल

1
चूंकि mallocमेमोरी प्राप्त करने में विफलता की परिस्थितियां कार्यान्वयन-परिभाषित हैं, इसलिए एक कार्यान्वयन केवल यह परिभाषित कर सकता है कि आकार -० का आवंटन हमेशा असंतोषजनक ( ENOMEM) है, और अब malloc(0)० (साथ errno==ENOMEM) लौटना सुसंगत है। :-)
आर .. गिटहब स्टॉप मदद

6
क्या आप reallocएक पॉइंटर द्वारा लौटा सकते हैं malloc(0)? क्या आप कर सकते हैं realloc((char*)NULL)?
ब्रैडेन बेस्ट

3
@ ब्रैडेन दोनों को सर्वश्रेष्ठ हाँ।
chux -

11

मॉलोक (0) व्यवहार विशिष्ट कार्यान्वयन है। लाइब्रेरी NULL को वापस कर सकती है या उसके पास नियमित मैलाक व्यवहार है, जिसमें कोई मेमोरी आवंटित नहीं है। जो कुछ भी करता है, वह कहीं न कहीं दस्तावेज होना चाहिए।

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

एक गैर नल मॉलोक (0) पॉइंटर को फिर से करना संभव है।

हालांकि एक मॉलोक (0) शब्दशः का बहुत अधिक उपयोग नहीं होता है। इसका उपयोग ज्यादातर तब किया जाता है जब एक गतिशील आवंटन शून्य बाइट होता है और आपने इसे मान्य करने की परवाह नहीं की।


9
malloc()कहीं न कहीं "हाउसकीपिंग की जानकारी" रखनी चाहिए (उदाहरण के लिए आवंटित ब्लॉक का यह आकार, और अन्य सहायक डेटा)। इसलिए, यदि malloc(0)वह वापस नहीं आता है , तो NULLयह उस जानकारी को संग्रहीत करने के लिए मेमोरी का उपयोग करेगा, और यदि नहीं free(), तो मेमोरी रिसाव का गठन करेगा।
आलोक सिंघल

मल्लोक कार्यान्वयन रिकॉर्ड रखते हुए प्रदर्शन करते हैं जो प्रति सूचक आकार के शीर्ष पर लौटे प्रति निश्चित डेटा जोड़ सकते हैं।
user7116

1
खपत की गई मेमोरी और आवंटित की गई मेमोरी का मतलब एक ही बात नहीं है। इस मामले में, अधिकांश कार्यान्वयन एक अद्वितीय सूचक लौटाएगा। इसका मतलब है कि पता स्थान का एक हिस्सा उस सूचक के लिए बलिदान करने की आवश्यकता है। आवंटनकर्ता के आधार पर, इसका वास्तव में मतलब हो सकता है कि यह 1 बाइट या अधिक आवंटित करेगा।
कॉइनकॉइन

1
पुस्तकालय जो चाहे कर सकता है - ठीक है, यह या तो एक अद्वितीय सूचक लौटा सकता है कि कोई अन्य malloc()वापस नहीं लौटेगा, या वापस नहीं लौटेगा NULL
आलोक सिंघल

1
@jldupont: कम से कम Microsoft C रन-टाइम लाइब्रेरी के लिए एक अद्वितीय पॉइंटर देता है malloc(0)। हालाँकि, मानक C लाइब्रेरी के बहुत ही कार्यान्वयन में, NULL को realloc(ptr, 0)मुक्त ptrऔर लौटाता है।
मेडिनोक

5

इस पृष्ठ पर कहीं और उत्तर है जो "मॉलोक (0) शुरू होता है, जो एक वैध मेमोरी एड्रेस लौटाएगा और जिसकी रेंज पॉइंटर के प्रकार पर निर्भर करेगी जिसे मेमोरी आवंटित की जा रही है"। यह कथन गलत है (मेरे पास सीधे उस उत्तर पर टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा नहीं है, इसलिए इस टिप्पणी को सीधे वहां नहीं डाल सकते हैं)।

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


4

malloc(0)मेरे लिए कोई मतलब नहीं है, जब तक कि कोड कार्यान्वयन के लिए विशिष्ट व्यवहार पर निर्भर न हो। यदि कोड पोर्टेबल होने का मतलब है, तो यह इस तथ्य के लिए जिम्मेदार है कि एक NULL से वापसी malloc(0)विफलता नहीं है। तो क्यों न केवल NULL को artistवैसे भी असाइन किया जाए , क्योंकि यह एक वैध सफल परिणाम है, और कम कोड है, और इससे आपके रखरखाव प्रोग्रामर को समय नहीं लगेगा?

malloc(SOME_CONSTANT_THAT_MIGHT_BE_ZERO)या malloc(some_variable_which_might_be_zero)शायद उनके उपयोग हो सकते हैं, हालांकि फिर से आपको अतिरिक्त ध्यान रखना होगा कि एक पूर्ण रिटर्न को असफलता के रूप में न मानें यदि मान 0 है, लेकिन 0 आकार ठीक माना जाता है।


3

यहाँ बहुत सारे आधे सही उत्तर हैं, इसलिए यहाँ कठिन तथ्य हैं। malloc()कहते हैं कि आदमी के लिए पेज :

यदि आकार 0 है, तो मॉलॉक () या तो NULL, या एक अद्वितीय सूचक मान लौटाता है जिसे बाद में मुफ्त में सफलतापूर्वक पास किया जा सकता है ()।

इसका मतलब है कि, इस बात की कोई गारंटी नहीं है कि इसका परिणाम malloc(0)या तो अद्वितीय है या नहीं NULL। केवल गारंटी, की परिभाषा द्वारा प्रदान की जाती है free(), फिर से, यहां वह है जो मैन-पेज कहता है:

यदि ptr NULL है, तो कोई भी ऑपरेशन नहीं किया जाता है।

इसलिए, जो भी malloc(0)रिटर्न देता है, उसे सुरक्षित रूप से पारित किया जा सकता है free()। लेकिन एक NULLसूचक हो सकता है ।

नतीजतन, लेखन artist = malloc(0); किसी भी तरह से लेखन से बेहतर नहीं है artist = NULL;


1
बहुत बुरा कार्यान्वयन को गैर-अशक्त, गैर-अद्वितीय सूचक वापस करने की अनुमति नहीं है। इस तरह, malloc(0)0x1 पर वापस जा सकते हैं, कह सकते हैं, और 0x1 के free()विशेष-मामले की जांच कर सकते हैं , जैसा कि 0x0 के लिए है।
टॉड लेहमन

3
@ टॉड लेहमैन जैसा कि आप सुझाव देते हैं, एक कार्यान्वयन हो सकता है। सी कल्पना निर्दिष्ट नहीं करती है कि परिणाम " NULL, या एक अद्वितीय सूचक" होना चाहिए । इसके बजाय 'या तो एक शून्य सूचक या आवंटित स्थान के लिए एक संकेतक "। कोई अद्वितीय आवश्यकता नहीं है। ओटीओएच, एक गैर-विशिष्ट विशेष मान लौटाते हुए कोड को बाधित कर सकता है जो अद्वितीय मूल्यों पर मायने रखता है। शायद एसओ के लिए एक कोने का मामला सवाल है।
chux

manकार्यान्वयन के रूप में अच्छी तरह से दस्तावेज़ को परिभाषित रूप में इस्तेमाल किया जा सकता है। इस मामले में यह नहीं है, लेकिन यह अभी भी सामान्य सी के लिए एक विहित स्रोत नहीं है
लुंडिन

@ लुंडिन सच। लेकिन मैन-पेज सी मानक से बहुत अधिक सुलभ हैं, और जीएनयू / लिनक्स सिस्टम पर मैन-पेज आमतौर पर काफी अच्छी तरह से प्रलेखित करते हैं कि कौन सा मानक लागू होता है। किन भागों की जानकारी के साथ, किस मानक का पालन करना चाहिए, यह अलग-अलग होना चाहिए। मुझे लग रहा है कि वे दोनों सटीक होना चाहते हैं, और हर एक बिट को विज्ञापित करते हैं जो एक GNU एक्सटेंशन है ...
cmaster - reicaate monica

3

आपको ऐसा क्यों नहीं करना चाहिए ...

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

इस उदाहरण पर विचार करें, जहां आगे दिए गए पते के माध्यम से मेमोरी तक पहुंचना भ्रष्ट होगा यदि iff का आकार शून्य है और कार्यान्वयन एक गैर NULL मान लौटाता है।

size_t size;

/* Initialize size, possibly by user-controlled input */

int *list = (int *)malloc(size);
if (list == NULL) {
  /* Handle allocation error */
}
else {
  /* Continue processing list */
}

CERT कोडिंग मानकों का यह सिक्योर कोडिंग पेज देखें जहां मैंने आगे पढ़ने के लिए ऊपर का उदाहरण लिया है।


लिंक को स्थानांतरित कर दिया गया है: wiki.sei.cmu.edu/confluence/display/c/…
Cacahuete Frito

2

बेशक, मैंने इसे पहले कभी नहीं देखा है, यह पहली बार है जब मैंने इस वाक्यविन्यास को देखा है, एक कह सकता है, फ़ंक्शन ओवरकिल का एक क्लासिक मामला। रीड के जवाब के संयोजन में, मैं यह बताना चाहता हूं कि एक समान चीज है, जो एक अतिभारित फ़ंक्शन की तरह दिखाई देती है realloc:

  • foo गैर-शून्य है और आकार शून्य है realloc(foo, size);। जब आप एक गैर-पूर्ण सूचक और शून्य के आकार में पास हो जाते हैं, तो realloc ऐसा व्यवहार करता है मानो आपने फ्री () कहा हो।
  • foo NULL है और आकार गैर-शून्य और 1 से अधिक है realloc(foo, size);। जब आप एक NULL पॉइंटर में पास होते हैं और आकार गैर-शून्य होता है, तो realloc ऐसा व्यवहार करता है मानो आपने Malloc (…) कहा हो

आशा है कि यह मदद करता है, सर्वश्रेष्ठ संबंध, टॉम।


1

वास्तव में किए गए प्रश्न का उत्तर देने के लिए: ऐसा करने का कोई कारण नहीं है


0

मॉलॉक (0) NULL या एक वैध पॉइंटर लौटाएगा जिसे मुफ्त में पास किया जा सकता है। और यद्यपि यह स्मृति की तरह लगता है कि यह इंगित करता है कि यह बेकार है या इसे लिखा या पढ़ा नहीं जा सकता है, यह हमेशा सच नहीं होता है। :)

int *i = malloc(0);
*i = 100;
printf("%d", *i);

हम यहां एक विभाजन दोष की उम्मीद करते हैं, लेकिन आश्चर्यजनक रूप से, यह 100 प्रिंट करता है! इसका कारण यह है कि जब हम पहली बार मॉलॉक कहते हैं तो मॉलॉक वास्तव में स्मृति का एक बड़ा हिस्सा मांगता है। उसके बाद मॉलॉक के लिए हर कॉल, उस बड़े चंक से मेमोरी का उपयोग करता है। उसके बाद ही बहुत बड़ा हिस्सा खत्म हो जाता है, नई याददाश्त मांगी जाती है।

मॉलोक (0) का उपयोग: यदि आप ऐसी स्थिति में हैं, जहां आप चाहते हैं कि बाद में होने वाले मॉलोक कॉल तेजी से हों, तो मॉलोक (0) को यह आपके लिए करना चाहिए (किनारे के मामलों को छोड़कर)।


1
लेखन *iआपके मामले में दुर्घटनाग्रस्त नहीं हो सकता है, लेकिन यह अपरिभाषित व्यवहार है। नाक राक्षसों के लिए बाहर देखो!
जॉन ड्वोरक

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

मुझे पता है: इस प्रश्न पर सुपर लेट टिप्पणी। लेकिन कभी-कभी इसका उपयोग malloc(0)होता है जिसका उल्लेख नहीं किया गया है। उन कार्यान्वयनों पर जहां यह एक गैर-पूर्ण मान लौटाता है, विशेष रूप से DEBUG बिल्ड में, यह संभवतः आपके द्वारा मांगे गए से अधिक आवंटित करता है, और आपको सूचक को इसके आंतरिक हेडर को पिछले करने के लिए देता है। यह आपको वास्तविक स्मृति उपयोग के लिए एक अनुभव प्राप्त करने की अनुमति देता है यदि आपको यह आवंटन की श्रृंखला से पहले और बाद में मिलता है। जैसे: void* before = malloc(0); ... void* after = malloc(0); long long total = after - before;या कुछ इस तरह।
जेसी चिशोल्म

मैंने ब्रेन कर्निघन और डेनिस रिची की "द सी प्रोग्रामिंग भाषा" पढ़ी और मुझे इसके बारे में कुछ भी कहना याद नहीं है malloc(0)। क्या आप यह कह सकते हैं कि आप किस अध्याय का उल्लेख कर रहे हैं? एक सटीक उद्धरण प्रदान करना भी अच्छा होगा।
Андрей Беньковский

0

विंडोज में:

  • void *p = malloc(0);स्थानीय ढेर पर एक शून्य-लंबाई बफर आवंटित करेगा। पॉइंटर लौटाया गया एक मान्य हीप पॉइंटर है।
  • mallocअंततः HeapAllocडिफॉल्ट C रनटाइम हीप का उपयोग करके कॉल करता है जो तब कॉल करता है RtlAllocateHeap, आदि।
  • free(p);HeapFreeढेर पर 0-लंबाई बफर को मुक्त करने के लिए उपयोग करता है। इसे मुक्त नहीं करने से स्मृति रिसाव होगा।

0

यह वास्तव में काफी उपयोगी है, और (जाहिर तौर पर IMHO), NULL पॉइंटर वापस करने का अनुमत व्यवहार टूट गया है। एक डायनेमिक पॉइंटर न केवल उस पर इंगित करने के लिए उपयोगी है, बल्कि इस तथ्य को भी बताता है कि यह अद्वितीय है। रिटर्निंग NULL उस दूसरी प्रॉपर्टी को हटा देता है। सभी एम्बेडेड मैलोडो I कार्यक्रम (वास्तव में अक्सर) में यह व्यवहार होता है।


-1

निश्चित नहीं, कुछ रैंडम मॉलोक सोर्स कोड के अनुसार, मुझे NULL के रिटर्न वैल्यू में 0 रिजल्ट का इनपुट मिला है। तो यह कलाकार सूचक को NULL को स्थापित करने का एक पागल तरीका है।

http://www.raspberryginger.com/jbailey/minix/html/lib_2ansi_2malloc_8c-source.html


-2

वैलग्राइंड मेमोरी चेक टूल के साथ चलने के बाद यहां विश्लेषण है।

==16740== Command: ./malloc0
==16740==
p1 = 0x5204040
==16740==
==16740== HEAP SUMMARY:
==16740==     in use at exit: 0 bytes in 0 blocks
==16740==   total heap usage: 2 allocs, 2 frees, 1,024 bytes allocated
==16740==
==16740== All heap blocks were freed -- no leaks are possible

और यहाँ मेरा नमूना कोड है:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
   //int i;
   char *p1;

   p1 = (char *)malloc(0);
   printf("p1 = %p\n", p1);

   free(p1);

   return 0;

}

डिफ़ॉल्ट रूप से 1024 बाइट आवंटित किया जाता है। अगर मैं मॉलॉक का आकार बढ़ाता हूं, तो आवंटित बाइट्स 1025 और बढ़ जाएंगे।


-3

रीड कोपसी के जवाब और मैलोक के मैन पेज के अनुसार , मैंने परीक्षण करने के लिए कुछ उदाहरण लिखे। और मुझे पता चला कि मॉलॉक (0) हमेशा इसे एक अद्वितीय मूल्य देगा। मेरा उदाहरण देखें:

char *ptr;
if( (ptr = (char *) malloc(0)) == NULL )
    puts("Got a null pointer");
else
    puts("Got a valid pointer");

आउटपुट "गॉट ए वैलिड पॉइंटर" होगा, जिसका मतलब है ptrकि यह शून्य नहीं है।


-6

malloc(0)एक मान्य मेमोरी पता लौटाएगा और जिसकी सीमा सूचक के प्रकार पर निर्भर करेगी जिसे मेमोरी आवंटित की जा रही है। इसके अलावा, आप मेमोरी क्षेत्र में मान असाइन कर सकते हैं लेकिन इसका उपयोग सूचक के प्रकार के साथ सीमा में होना चाहिए। आप आवंटित मेमोरी को भी मुक्त कर सकते हैं। मैं इसे एक उदाहरण से समझाऊंगा:

int *p=NULL;
p=(int *)malloc(0);
free(p);

उपरोक्त कोड gccलिनक्स मशीन पर एक संकलक में ठीक काम करेगा । यदि आपके पास 32 बिट कंपाइलर है तो आप पूर्णांक रेंज में मान प्रदान कर सकते हैं, यानी -2147483648 से 2147483647। अक्षर के लिए भी यही लागू होता है। कृपया ध्यान दें कि यदि घोषित प्रकार के पॉइंटर को बदल दिया जाता है, तो mallocटाइपकास्ट की परवाह किए बिना मानों की श्रेणी बदल जाएगी

unsigned char *p=NULL;
p =(char *)malloc(0);
free(p);

p जब से यह अहस्ताक्षरित int घोषित किया जाता है, तब से यह 0 से 255 तक का मूल्य लेगा।


5
क्रेलेन यह इंगित करने में सही है कि यह उत्तर गलत है: malloc()कलाकारों के बारे में कुछ भी नहीं जानता है (जो वास्तव में सी में पूरी तरह से सुपरफ्लुएंट है)। की वापसी मूल्य को परिभाषित malloc(0)करने से अपरिभाषित व्यवहार शुरू हो जाएगा।
विस्फ़ोटक - मोनिका

-6

यहाँ एक गलत धारणा को ठीक करने के लिए:

artist = (char *) malloc(0);कभी लौट कर नहीं आएगा NULL; यह वैसा नहीं है artist = NULL;। एक साधारण प्रोग्राम लिखें और तुलना artistकरें NULLif (artist == NULL)असत्य है और if (artist)सत्य है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.