जवाबों:
विनिर्देशों के अनुसार, मॉलोक (0) या तो "अशक्त सूचक या एक अद्वितीय सूचक होगा जो सफलतापूर्वक मुक्त ()" में पारित किया जा सकता है।
यह मूल रूप से आपको कुछ भी आवंटित करने की अनुमति नहीं देता है, लेकिन फिर भी "कलाकार" चर को बिना किसी चिंता के मुफ्त () में कॉल करें। व्यावहारिक उद्देश्यों के लिए, ऐसा करना बहुत अधिक है:
artist = NULL;
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
:।
malloc(0)
एक वैध पॉइंटर लौटाया जाता है, तो malloc()
लौटने का NULL
मतलब हमेशा "विफलता" होता है, और 0
अब कोई विशेष मामला नहीं है, जो अधिक सुसंगत है।
malloc
मेमोरी प्राप्त करने में विफलता की परिस्थितियां कार्यान्वयन-परिभाषित हैं, इसलिए एक कार्यान्वयन केवल यह परिभाषित कर सकता है कि आकार -० का आवंटन हमेशा असंतोषजनक ( ENOMEM
) है, और अब malloc(0)
० (साथ errno==ENOMEM
) लौटना सुसंगत है। :-)
realloc
एक पॉइंटर द्वारा लौटा सकते हैं malloc(0)
? क्या आप कर सकते हैं realloc((char*)NULL)
?
मॉलोक (0) व्यवहार विशिष्ट कार्यान्वयन है। लाइब्रेरी NULL को वापस कर सकती है या उसके पास नियमित मैलाक व्यवहार है, जिसमें कोई मेमोरी आवंटित नहीं है। जो कुछ भी करता है, वह कहीं न कहीं दस्तावेज होना चाहिए।
आमतौर पर, यह एक ऐसा पॉइंटर देता है जो वैध और अनोखा होता है, लेकिन इसे डीरेल्ड नहीं किया जाना चाहिए। यह भी ध्यान दें कि यह मेमोरी का उपभोग कर सकता है, हालांकि यह वास्तव में कुछ भी आवंटित नहीं करता था।
एक गैर नल मॉलोक (0) पॉइंटर को फिर से करना संभव है।
हालांकि एक मॉलोक (0) शब्दशः का बहुत अधिक उपयोग नहीं होता है। इसका उपयोग ज्यादातर तब किया जाता है जब एक गतिशील आवंटन शून्य बाइट होता है और आपने इसे मान्य करने की परवाह नहीं की।
malloc()
कहीं न कहीं "हाउसकीपिंग की जानकारी" रखनी चाहिए (उदाहरण के लिए आवंटित ब्लॉक का यह आकार, और अन्य सहायक डेटा)। इसलिए, यदि malloc(0)
वह वापस नहीं आता है , तो NULL
यह उस जानकारी को संग्रहीत करने के लिए मेमोरी का उपयोग करेगा, और यदि नहीं free()
, तो मेमोरी रिसाव का गठन करेगा।
malloc()
वापस नहीं लौटेगा, या वापस नहीं लौटेगा NULL
।
malloc(0)
। हालाँकि, मानक C लाइब्रेरी के बहुत ही कार्यान्वयन में, NULL को realloc(ptr, 0)
मुक्त ptr
और लौटाता है।
इस पृष्ठ पर कहीं और उत्तर है जो "मॉलोक (0) शुरू होता है, जो एक वैध मेमोरी एड्रेस लौटाएगा और जिसकी रेंज पॉइंटर के प्रकार पर निर्भर करेगी जिसे मेमोरी आवंटित की जा रही है"। यह कथन गलत है (मेरे पास सीधे उस उत्तर पर टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा नहीं है, इसलिए इस टिप्पणी को सीधे वहां नहीं डाल सकते हैं)।
मॉलॉक (0) करना स्वचालित रूप से सही आकार की मेमोरी आवंटित नहीं करेगा। मॉलॉक फ़ंक्शन इस बात से अनजान है कि आप उसके परिणाम को क्या बता रहे हैं। मॉलॉक फ़ंक्शन शुद्ध रूप से उस आकार संख्या पर निर्भर करता है जिसे आप इसके तर्क के रूप में देते हैं। एक उदाहरण रखने के लिए पर्याप्त भंडारण प्राप्त करने के लिए आपको मॉलोक (साइज़ोफ़ (इंट)) करने की ज़रूरत है, उदाहरण के लिए, 0 नहीं।
malloc(0)
मेरे लिए कोई मतलब नहीं है, जब तक कि कोड कार्यान्वयन के लिए विशिष्ट व्यवहार पर निर्भर न हो। यदि कोड पोर्टेबल होने का मतलब है, तो यह इस तथ्य के लिए जिम्मेदार है कि एक NULL से वापसी malloc(0)
विफलता नहीं है। तो क्यों न केवल NULL को artist
वैसे भी असाइन किया जाए , क्योंकि यह एक वैध सफल परिणाम है, और कम कोड है, और इससे आपके रखरखाव प्रोग्रामर को समय नहीं लगेगा?
malloc(SOME_CONSTANT_THAT_MIGHT_BE_ZERO)
या malloc(some_variable_which_might_be_zero)
शायद उनके उपयोग हो सकते हैं, हालांकि फिर से आपको अतिरिक्त ध्यान रखना होगा कि एक पूर्ण रिटर्न को असफलता के रूप में न मानें यदि मान 0 है, लेकिन 0 आकार ठीक माना जाता है।
यहाँ बहुत सारे आधे सही उत्तर हैं, इसलिए यहाँ कठिन तथ्य हैं। malloc()
कहते हैं कि आदमी के लिए पेज :
यदि आकार 0 है, तो मॉलॉक () या तो NULL, या एक अद्वितीय सूचक मान लौटाता है जिसे बाद में मुफ्त में सफलतापूर्वक पास किया जा सकता है ()।
इसका मतलब है कि, इस बात की कोई गारंटी नहीं है कि इसका परिणाम malloc(0)
या तो अद्वितीय है या नहीं NULL। केवल गारंटी, की परिभाषा द्वारा प्रदान की जाती है free()
, फिर से, यहां वह है जो मैन-पेज कहता है:
यदि ptr NULL है, तो कोई भी ऑपरेशन नहीं किया जाता है।
इसलिए, जो भी malloc(0)
रिटर्न देता है, उसे सुरक्षित रूप से पारित किया जा सकता है free()
। लेकिन एक NULL
सूचक हो सकता है ।
नतीजतन, लेखन artist = malloc(0);
किसी भी तरह से लेखन से बेहतर नहीं है artist = NULL;
malloc(0)
0x1 पर वापस जा सकते हैं, कह सकते हैं, और 0x1 के free()
विशेष-मामले की जांच कर सकते हैं , जैसा कि 0x0 के लिए है।
NULL
, या एक अद्वितीय सूचक" होना चाहिए । इसके बजाय 'या तो एक शून्य सूचक या आवंटित स्थान के लिए एक संकेतक "। कोई अद्वितीय आवश्यकता नहीं है। ओटीओएच, एक गैर-विशिष्ट विशेष मान लौटाते हुए कोड को बाधित कर सकता है जो अद्वितीय मूल्यों पर मायने रखता है। शायद एसओ के लिए एक कोने का मामला सवाल है।
man
कार्यान्वयन के रूप में अच्छी तरह से दस्तावेज़ को परिभाषित रूप में इस्तेमाल किया जा सकता है। इस मामले में यह नहीं है, लेकिन यह अभी भी सामान्य सी के लिए एक विहित स्रोत नहीं है
आपको ऐसा क्यों नहीं करना चाहिए ...
चूंकि मॉलॉक का वापसी मूल्य कार्यान्वयन पर निर्भर है, इसलिए आपको एक पूर्ण सूचक या कुछ अन्य पता वापस मिल सकता है। यह हीप-बफर ओवरफ्लो बनाते हुए समाप्त हो सकता है यदि त्रुटि हैंडलिंग कोड आकार और लौटाए गए मूल्य दोनों की जांच नहीं करता है, जिससे स्थिरता के मुद्दे (क्रैश) या इससे भी बदतर सुरक्षा मुद्दे हो सकते हैं।
इस उदाहरण पर विचार करें, जहां आगे दिए गए पते के माध्यम से मेमोरी तक पहुंचना भ्रष्ट होगा यदि 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 कोडिंग मानकों का यह सिक्योर कोडिंग पेज देखें जहां मैंने आगे पढ़ने के लिए ऊपर का उदाहरण लिया है।
बेशक, मैंने इसे पहले कभी नहीं देखा है, यह पहली बार है जब मैंने इस वाक्यविन्यास को देखा है, एक कह सकता है, फ़ंक्शन ओवरकिल का एक क्लासिक मामला। रीड के जवाब के संयोजन में, मैं यह बताना चाहता हूं कि एक समान चीज है, जो एक अतिभारित फ़ंक्शन की तरह दिखाई देती है realloc
:
realloc(foo, size);
। जब आप एक गैर-पूर्ण सूचक और शून्य के आकार में पास हो जाते हैं, तो realloc ऐसा व्यवहार करता है मानो आपने फ्री () कहा हो।realloc(foo, size);
। जब आप एक NULL पॉइंटर में पास होते हैं और आकार गैर-शून्य होता है, तो realloc ऐसा व्यवहार करता है मानो आपने Malloc (…) कहा होआशा है कि यह मदद करता है, सर्वश्रेष्ठ संबंध, टॉम।
मॉलॉक (0) NULL या एक वैध पॉइंटर लौटाएगा जिसे मुफ्त में पास किया जा सकता है। और यद्यपि यह स्मृति की तरह लगता है कि यह इंगित करता है कि यह बेकार है या इसे लिखा या पढ़ा नहीं जा सकता है, यह हमेशा सच नहीं होता है। :)
int *i = malloc(0);
*i = 100;
printf("%d", *i);
हम यहां एक विभाजन दोष की उम्मीद करते हैं, लेकिन आश्चर्यजनक रूप से, यह 100 प्रिंट करता है! इसका कारण यह है कि जब हम पहली बार मॉलॉक कहते हैं तो मॉलॉक वास्तव में स्मृति का एक बड़ा हिस्सा मांगता है। उसके बाद मॉलॉक के लिए हर कॉल, उस बड़े चंक से मेमोरी का उपयोग करता है। उसके बाद ही बहुत बड़ा हिस्सा खत्म हो जाता है, नई याददाश्त मांगी जाती है।
मॉलोक (0) का उपयोग: यदि आप ऐसी स्थिति में हैं, जहां आप चाहते हैं कि बाद में होने वाले मॉलोक कॉल तेजी से हों, तो मॉलोक (0) को यह आपके लिए करना चाहिए (किनारे के मामलों को छोड़कर)।
*i
आपके मामले में दुर्घटनाग्रस्त नहीं हो सकता है, लेकिन यह अपरिभाषित व्यवहार है। नाक राक्षसों के लिए बाहर देखो!
malloc(0)
होता है जिसका उल्लेख नहीं किया गया है। उन कार्यान्वयनों पर जहां यह एक गैर-पूर्ण मान लौटाता है, विशेष रूप से DEBUG बिल्ड में, यह संभवतः आपके द्वारा मांगे गए से अधिक आवंटित करता है, और आपको सूचक को इसके आंतरिक हेडर को पिछले करने के लिए देता है। यह आपको वास्तविक स्मृति उपयोग के लिए एक अनुभव प्राप्त करने की अनुमति देता है यदि आपको यह आवंटन की श्रृंखला से पहले और बाद में मिलता है। जैसे: void* before = malloc(0); ... void* after = malloc(0); long long total = after - before;
या कुछ इस तरह।
malloc(0)
। क्या आप यह कह सकते हैं कि आप किस अध्याय का उल्लेख कर रहे हैं? एक सटीक उद्धरण प्रदान करना भी अच्छा होगा।
विंडोज में:
void *p = malloc(0);
स्थानीय ढेर पर एक शून्य-लंबाई बफर आवंटित करेगा। पॉइंटर लौटाया गया एक मान्य हीप पॉइंटर है।malloc
अंततः HeapAlloc
डिफॉल्ट C रनटाइम हीप का उपयोग करके कॉल करता है जो तब कॉल करता है RtlAllocateHeap
, आदि।free(p);
HeapFree
ढेर पर 0-लंबाई बफर को मुक्त करने के लिए उपयोग करता है। इसे मुक्त नहीं करने से स्मृति रिसाव होगा।यह वास्तव में काफी उपयोगी है, और (जाहिर तौर पर IMHO), NULL पॉइंटर वापस करने का अनुमत व्यवहार टूट गया है। एक डायनेमिक पॉइंटर न केवल उस पर इंगित करने के लिए उपयोगी है, बल्कि इस तथ्य को भी बताता है कि यह अद्वितीय है। रिटर्निंग NULL उस दूसरी प्रॉपर्टी को हटा देता है। सभी एम्बेडेड मैलोडो I कार्यक्रम (वास्तव में अक्सर) में यह व्यवहार होता है।
निश्चित नहीं, कुछ रैंडम मॉलोक सोर्स कोड के अनुसार, मुझे NULL के रिटर्न वैल्यू में 0 रिजल्ट का इनपुट मिला है। तो यह कलाकार सूचक को NULL को स्थापित करने का एक पागल तरीका है।
http://www.raspberryginger.com/jbailey/minix/html/lib_2ansi_2malloc_8c-source.html
वैलग्राइंड मेमोरी चेक टूल के साथ चलने के बाद यहां विश्लेषण है।
==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 और बढ़ जाएंगे।
रीड कोपसी के जवाब और मैलोक के मैन पेज के अनुसार , मैंने परीक्षण करने के लिए कुछ उदाहरण लिखे। और मुझे पता चला कि मॉलॉक (0) हमेशा इसे एक अद्वितीय मूल्य देगा। मेरा उदाहरण देखें:
char *ptr;
if( (ptr = (char *) malloc(0)) == NULL )
puts("Got a null pointer");
else
puts("Got a valid pointer");
आउटपुट "गॉट ए वैलिड पॉइंटर" होगा, जिसका मतलब है ptr
कि यह शून्य नहीं है।
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 तक का मूल्य लेगा।
malloc()
कलाकारों के बारे में कुछ भी नहीं जानता है (जो वास्तव में सी में पूरी तरह से सुपरफ्लुएंट है)। की वापसी मूल्य को परिभाषित malloc(0)
करने से अपरिभाषित व्यवहार शुरू हो जाएगा।
यहाँ एक गलत धारणा को ठीक करने के लिए:
artist = (char *) malloc(0);
कभी लौट कर नहीं आएगा NULL
; यह वैसा नहीं है artist = NULL;
। एक साधारण प्रोग्राम लिखें और तुलना artist
करें NULL
। if (artist == NULL)
असत्य है और if (artist)
सत्य है।