2009-07-02 13 views
39

बहुत ही सरल सवाल है, मैं निम्नलिखित कार्यक्रम बनाया:शून्य आकार malloc

#include <stdlib.h> 
int main(int argc, char ** argv) 
{ 
    void * ptr; 
    ptr = malloc(0); 
    free(ptr); 
} 

और यह मेरे मशीन पर SEGFAULT नहीं है। क्या यह stdlib malloc का एक पोर्टेबल व्यवहार है और मुफ्त है, या क्या मैं परेशानी की तलाश में हूं?

संपादित करें: गैर पोर्टेबल लगता है कि मॉलोक द्वारा लौटाया गया मूल्य क्या है। प्रश्न malloc (0) + मुक्त संयोजन के बारे में है, पीटीआर के मूल्य नहीं।

+1

भालू है कि, अगर यह काम नहीं किया, वहाँ रहना होगा सुझाव है कि विशेष मामले का एक बहुत कोड। लोग हर समय एक चर या अभिव्यक्ति के आधार पर कई बाइट्स को मॉलोक करेंगे, और हर बार शून्य की जांच करना अजीब होगा। –

+0

संबंधित: http://stackoverflow.com/questions/2022335/whats-the-point-in-malloc0 – jldupont

+0

मुझे पता है: इस बंद प्रश्न पर सुपर देर से टिप्पणी। लेकिन 'malloc (0) 'के लिए _sever_ का उपयोग किया गया है जिसका उल्लेख नहीं है। उन कार्यान्वयनों पर जहां यह एक गैर-कुल मूल्य देता है, खासकर डेब्यूग बिल्ड में, यह आपके द्वारा पूछे जाने वाले अधिक से अधिक आवंटित करता है, और आपको अपने आंतरिक शीर्षलेख को ठीक करने के लिए सूचक देता है। यदि आपको आवंटन की श्रृंखला से पहले और बाद में यह मिलता है तो यह आपको वास्तविक स्मृति उपयोग के लिए _feel_ प्राप्त करने की अनुमति देता है। –

उत्तर

54

व्यवहार कार्यान्वयन परिभाषित किया गया है, आपको या तो एक पूर्ण सूचक या पता प्राप्त होगा। प्राप्त सूचक के लिए मुफ्त कॉलिंग लेकिन एक समस्या का कारण नहीं होना चाहिए के बाद से:

  • मुक्त (शून्य), कोई आपरेशन
  • मुक्त (पता) किया जाता है ठीक है, अगर पता malloc से प्राप्त किया गया था ठीक है (या अन्य कॉलोक इत्यादि की तरह)
23

इसे पूर्ण वापस करने की अनुमति है, और इसे एक गैर-नल पॉइंटर वापस करने की अनुमति है, जिसे आप अस्वीकार नहीं कर सकते हैं। दोनों तरीकों मानक (7.20.3) द्वारा स्वीकृत किए जाते हैं:

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

+1

यह वास्तव में सवाल नहीं पूछा गया है। मुझे मॉलोक द्वारा दिए गए मान के बारे में परवाह नहीं है, लेकिन मॉलोक (0) द्वारा लौटाए गए पॉइंटर पर मुफ्त कॉल करने के बारे में। – shodanex

+2

यह अभी भी एक बहुत अच्छा जवाब है क्योंकि कुंजी के जवाब के साथ यह व्यवहार पर एक संपूर्ण अवलोकन देता है। – schnaader

3

परेशानी के लिए क्षमा करें, मैं आदमी पृष्ठों को पढ़ लिया है चाहिए:

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

मुफ्त() पीआरटी द्वारा इंगित मेमोरी स्पेस को मुक्त करता है, जिसे पिछले कॉल द्वारा malloc(), calloc() या realloc() में वापस किया जाना चाहिए। अन्यथा, या मुक्त (पीआरटी) पहले से ही पहले ही बुलाया गया है, अपरिभाषित व्यवहार होता है। यदि पीआरटी न्यूल है, तो कोई ऑपरेशन नहीं किया जाता है।

ऐसा लगता है यह कम से कम

+4

आरटीएफएम :) http://en.wikipedia.org/wiki/RTFM –

1

libc gnu & पैक्स की टिप्पणी libt ध्यान में रखते हुए अद्यतन के लिए सच है:

malloc बुला के व्यवहार (0) कार्यान्वयन निर्भर या दूसरे शब्दों में गैर पोर्टेबल है और अपरिभाषित।

अधिक जानकारी के लिए CFaq प्रश्न से लिंक करें।

+2

आईएसओ मानकों परिभाषित, कार्यान्वयन-परिभाषित और अपरिभाषित के बीच एक बहुत स्पष्ट भेद बनाता है। तुम भी। कार्यान्वयन-परिभाषित का अर्थ यह है कि * परिभाषित किया गया है लेकिन उस कार्यान्वयन के लिए डॉको आपको बताएगा कि यह क्या करता है। अपरिभाषित मतलब यह है कि यह * कुछ भी * कर सकता है * ब्रह्मांड के कुल विनाश सहित, लेकिन इतनी ही सीमित नहीं है। – paxdiablo

+0

स्पष्टीकरण के लिए धन्यवाद (और नीचे वोट ;-))। मैंने शब्द को "अपरिभाषित" शब्द का उपयोग किया था। मेरी गलती। –

+0

आप faq को गलत समझते हैं। इसका मतलब यह नहीं है कि समग्र व्यवहार कार्यान्वयन परिभाषित किया गया है। इसका मतलब है कि नतीजा नल है या नहीं, कुछ अन्य मूल्य कार्यान्वयन परिभाषित किया गया है। उदाहरण के लिए, वैध व्यवहार में एक sigsegv भेजने में शामिल नहीं है। –

1

ग मानक

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

0

हालांकि यह कानूनी सी/सी ++ हो सकता है, यह एक बड़ी समस्या का संकेत है। मैं आमतौर पर इसे 'पॉइंटर स्लोपनेस' कहता हूं।

देखें "मॉलोक (0) या कॉलोक (0)", https://www.securecoding.cert.org/confluence/display/seccode/VOID+MEMxx-A.+Do+not+make+assumptions+about+the+result+of+malloc%280%29+or+calloc%280%29 के परिणाम के बारे में धारणा न करें।

+0

यह मॉलोक (0) के परिणाम के बारे में नहीं है, लेकिन इसके बारे में, मॉलोक (0) + मुफ्त संयोजन – shodanex

-2

मेरे अनुभव में, मैंने देखा है कि मॉलोक (0) एक सूचक लौटाता है जिसे मुक्त किया जा सकता है। लेकिन, यह बाद में malloc() कथन में SIGSEGV का कारण बनता है। और यह बेहद यादृच्छिक था।

जब मैंने चेक जोड़ा, तो आकार को आवंटित करने के लिए मॉलोक को कॉल न करने के लिए शून्य है, तो मैंने इससे छुटकारा पा लिया।

तो, मेरे मन में आकार के लिए स्मृति को आबंटित करने नहीं 0.

-Ashutosh

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