एक साधारण परीक्षण ऐप:
cout << new int[0] << endl;
आउटपुट:
0x876c0b8
तो ऐसा लगता है कि यह काम करता है। इस बारे में मानक क्या कहता है? क्या यह हमेशा स्मृति के खाली ब्लॉक को "आवंटित" करने के लिए कानूनी है?
एक साधारण परीक्षण ऐप:
cout << new int[0] << endl;
आउटपुट:
0x876c0b8
तो ऐसा लगता है कि यह काम करता है। इस बारे में मानक क्या कहता है? क्या यह हमेशा स्मृति के खाली ब्लॉक को "आवंटित" करने के लिए कानूनी है?
जवाबों:
5.3.4 / 7 से
जब एक प्रत्यक्ष-नए-घोषणाकर्ता में अभिव्यक्ति का मूल्य शून्य होता है, तो आवंटन फ़ंक्शन को कोई तत्व के साथ एक सरणी आवंटित करने के लिए कहा जाता है।
3.7.3.1/2 से
शून्य आकार के लिए एक अनुरोध के रूप में लौटे एक सूचक को निष्क्रिय करने का प्रभाव अपरिभाषित है।
भी
भले ही अंतरिक्ष का आकार [नए द्वारा] शून्य हो, अनुरोध विफल हो सकता है।
इसका मतलब है कि आप इसे कर सकते हैं, लेकिन आप कानूनी तौर पर (सभी प्लेटफार्मों पर अच्छी तरह से परिभाषित तरीके से) मेमोरी को निष्क्रिय नहीं कर सकते हैं जो आपको मिलती है - आप इसे केवल सरणी डिलीट करने के लिए पास कर सकते हैं - और आपको इसे हटाना चाहिए।
यहां एक दिलचस्प फुट-नोट (यानी मानक का एक आदर्श हिस्सा नहीं है, लेकिन एक्सपोजर प्रयोजनों के लिए शामिल है) 3.7.3.1/2 से वाक्य से जुड़ा हुआ है
[32। आशय यह है कि मॉलॉक () या कॉलोक () कॉल करके ऑपरेटर नया () लागू करने योग्य है, इसलिए नियम काफी हद तक समान हैं। C ++ एक गैर-शून्य पॉइंटर वापस करने के लिए शून्य अनुरोध की आवश्यकता में C से अलग है।]
new[]
एक delete[]
- जो भी आकार के साथ संतुलन नहीं रखते हैं, एक मेमोरी लीक होने की उम्मीद कर सकते हैं । विशेष रूप से, जब आप कॉल करते हैं, तो आपको new[i]
उससे थोड़ी अधिक मेमोरी की आवश्यकता होती है, जिसे आप सरणी के आकार को संग्रहीत करने के लिए delete[]
आवंटित करने की कोशिश कर रहे हैं (जो बाद में
हां, इस तरह से शून्य-आकार की सरणी आवंटित करना कानूनी है। लेकिन आपको इसे हटाना भी होगा।
int ar[0];
अवैध क्यों है नया ठीक है?
sizeof (type)
है कि शून्य वापस कभी नहीं आने की उम्मीद है। उदाहरण के लिए देखें: stackoverflow.com/questions/2632021/can-sizeof-return-0-zero
इस बारे में मानक क्या कहता है? क्या यह हमेशा स्मृति के खाली ब्लॉक को "आवंटित" करने के लिए कानूनी है?
प्रत्येक वस्तु की एक विशिष्ट पहचान होती है, अर्थात एक अद्वितीय पता, जिसका अर्थ है एक गैर-शून्य लंबाई (स्मृति की वास्तविक मात्रा चुपचाप बढ़ जाएगी, यदि आप शून्य बाइट्स के लिए पूछें)।
यदि आपने इनमें से एक से अधिक वस्तुओं का आवंटन किया है, तो आप पाएंगे कि उनके अलग-अलग पते हैं।
operator []
सरणी के आकार को भी कहीं संग्रहीत करता है (देखें isocpp.org/wiki/faq/freestore-mgmt#num-elems-in-new-array )। इसलिए यदि कार्यान्वयन डेटा के साथ बाइट काउंट को आवंटित करता है, तो यह केवल बाइट काउंट और डेटा के लिए 0 बाइट्स के लिए आवंटित कर सकता है, 1-पास्ट-लास्ट पॉइंटर लौटाता है।
operator new[]
को वापस करने के लिए होनी चाहिए। BTW, के new expression
कुछ अतिरिक्त नियम (5.3.4) हैं। मुझे ऐसा कोई सुराग नहीं मिला कि new
0 आकार के साथ वास्तव में कुछ भी आवंटित करने की आवश्यकता हो। क्षमा करें, मैंने अस्वीकार कर दिया क्योंकि मुझे पता है कि आपका उत्तर प्रश्नों का उत्तर नहीं दे रहा है, लेकिन कुछ विवादास्पद बयान दे रहा है।
new[]
किसी सीमा में पते वापस करने के लिए कार्यान्वयन हो, जहां कोई डायनामिक मेमोरी मैप नहीं है, इसलिए वास्तव में किसी भी मेमोरी का उपयोग नहीं करना है (पता स्थान का उपयोग करते समय)
while(!exitRequested) { char *p = new char[0]; delete [] p; }
रिसाइकलिंग पॉइंट्स के बिना लूप निष्पादित करने वाला कंप्यूटर संभवतः धूल में गिर जाएगा, इससे पहले कि वह संभवतः एड्रेस स्पेस से बाहर निकल जाए, लेकिन 32-बिट पॉइंटर्स वाले प्लेटफ़ॉर्म पर एक बहुत कम उचित धारणा।
हां इसके 0
साथ आकार ब्लॉक आवंटित करना पूरी तरह से कानूनी है new
। आप बस इसके साथ कुछ भी उपयोगी नहीं कर सकते हैं क्योंकि आपके पास पहुंचने के लिए कोई वैध डेटा नहीं है। int[0] = 5;
गैरकानूनी है।
हालांकि, मेरा मानना है कि मानक चीजों malloc(0)
को वापस करने की अनुमति देता है NULL
।
आपको अभी भी delete []
जो भी सूचक आपको आवंटन से वापस मिलेगा, उसकी आवश्यकता होगी ।
उत्सुकता से, C ++ के लिए आवश्यक है कि शून्य बाइट्स का अनुरोध करने पर भी ऑपरेटर नया वैध संकेतक लौटाए। (इस अजीब लगने वाले व्यवहार की आवश्यकता भाषा में कहीं और चीजों को सरल बनाती है।)
मैंने पाया कि प्रभावी C ++ थर्ड एडिशन ने इस तरह कहा "आइटम 51: नए लिखने के दौरान सम्मेलन का पालन करें और हटाएं"।
मैं आपको गारंटी देता हूं कि नए int [0] के बाद से आपने इसका परीक्षण किया है।
उदाहरण के लिए, का मेमोरी उपयोग
int **arr = new int*[1000000000];
से काफी छोटा है
int **arr = new int*[1000000000];
for(int i =0; i < 1000000000; i++) {
arr[i]=new int[0];
}
दूसरे कोड स्निपेट माइनस का पहला कोड स्निपेट का मेमोरी उपयोग कई नए int [0] के लिए उपयोग की जाने वाली मेमोरी है।