2012-03-15 12 views
11

विंडोज में निष्पादित होने पर नीचे दिया गया कोड एक पता देता है, हालांकि मैं इसे वापस लौटने की उम्मीद कर रहा था।मैलोक (0) विंडोज में एक गैर-शून्य पता क्यों देता है?

int main() 
{ 
    char *ptr = NULL; 
    ptr = malloc(0); 
    printf("malloc returned = %u\n", ptr); 

} 

मॉलोक के ऐसे कार्यान्वयन को क्या संकेत दे सकता था? क्या इसके पीछे कोई कारण है?

चूंकि, यह 0 बाइट मेमोरी है, मैंने किसी भी डेटा को लिखने का प्रयोग नहीं किया है। लेकिन, क्या इस स्मृति का उपयोग किसी भी चीज़ के लिए किया जा सकता है?

उत्तर

9

यह सिर्फ न्यूनतम आकार आप का अनुरोध कर रहे है क्या कर सकते हैं कहते हैं। और के बाद से वहाँ Win32 ढेर में कोई शून्य लंबाई ब्लॉक कर रहे हैं, आप कर सकते हैं:

void *p = malloc(0); 
// ... do some stuff in between... 
realloc(p, n); 

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

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

+0

+1 जैसा कि मैंने वास्तव में देखा है 1 व्यक्ति इसे अपने "लाभ" के लिए उपयोग करते हैं, जब वह एक लूप में विशेष मामला नहीं लेना चाहता था जो malloc'd/realloc'd स्मृति को बहुत बड़ा कर सकता है। – JimR

+1

आप एक शून्य सूचक को 'realloc' में पास कर सकते हैं, हालांकि, यह चाल किसी भी तरह से आवश्यक नहीं है। आप बस 'शून्य * पी = 0; 'भी कर सकते हैं। –

+0

@Steve यह वास्तव में एक चाल नहीं है। यह प्रोग्रामिंग और ढीले मंच विनिर्देशों का एक आर्टिफैक्ट है। परीक्षण के बिना, यह स्पष्ट नहीं है कि कैसे HeapRealloc (ढेर, HEAP_REALLOC_IN_PLACE_ONLY, 0, 4) व्यवहार करेगा, उदाहरण के लिए। – ActiveTrayPrntrTagDataStrDrvr

7

comp.lang.c पूछे जाने वाले प्रश्न के भीतर जवाब है कि: http://c-faq.com/ansi/malloc0.html

एएनएसआई/आईएसओ स्टैंडर्ड कहना है कि वह ऐसा कर सकते हैं कि या तो; व्यवहार कार्यान्वयन-परिभाषित है (प्रश्न 11.33 देखें)। पोर्टेबल कोड को या तो मॉलोक (0) को कॉल न करने की देखभाल करना चाहिए, या शून्य वापसी की संभावना के लिए तैयार रहना चाहिए।

+0

लेकिन, कुछ वैध मूल्य वापस करने के लिए कार्यान्वयन का क्या चयन होगा? क्या सभी मामलों में न्यूल वापस करने का अर्थ नहीं है? – Jay

+3

जरूरी नहीं है। मैं दूसरे अनुमान लगाने वाले कंपाइलर लेखकों के लिए चिल्लाता हूं, लेकिन एक कार्यान्वयनकर्ता मॉलोक को केवल 'शून्य' वापस लौटा सकता है अगर स्मृति को वास्तव में आवंटित नहीं किया जा सकता है। – CAbbott

+1

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

8

अपने प्रश्न संख्या के दूसरे भाग का उत्तर देने के लिए, स्मृति का उपयोग किसी भी चीज़ के लिए नहीं किया जा सकता है, क्योंकि "इसका पहुंच योग्य भाग" वापस दिए गए पते से 0 बाइट्स है।

आईआईआरसी यह गारंटी है कि अगर कार्यान्वयन गैर-शून्य हो जाता है, तो यह किसी अन्य वर्तमान आवंटित स्मृति ब्लॉक से पता होगा। तो सिद्धांत रूप में आप पते को एक अस्थायी अद्वितीय आईडी (सूचक प्रकार के) के रूप में उपयोग कर सकते हैं, हालांकि स्पष्ट रूप से एक अद्वितीय आईडी प्राप्त करने के कई अन्य तरीके हैं। और यहां तक ​​कि यदि आप इसके लिए इसका उपयोग करने जा रहे थे, malloc(1) बस malloc(0) और अधिक पोर्टेबल काम करेगा।

0

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

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

संबंधित मुद्दे