एक पॉइंटर के गुण शून्य लंबाई सरणी के लिए


21

विचार करें

int main()
{
    auto a = new int[0];
    delete[] a; // So there's no memory leak
}

प्रतिलिपि आरंभीकरण और विलोपन के बीच, क्या आपको सूचक को पढ़ने की अनुमति है a + 1?

इसके अलावा, क्या भाषा कंपाइलर को सेट aकरने की अनुमति देती है nullptr?


2
@ फ़ॉरनर: आप aनिश्चित रूप से पढ़ सकते हैं (आप निश्चित रूप से इसे नहीं कर सकते)।
बाथशी

8
@RasmiRanjanNayak: यह हॉगवॉश है।
बाथशीबा

2
@RasmiRanjanNayak ओह माय ... नहीं
टेड लिंगमो

1
@TedLyngmo: जब मैं कहता हूं "सूचक को पढ़ें a + 1", तो निम्न कोड auto b = a + 1;अपरिभाषित व्यवहार है? (मुझे लगता है ऐसा है)।
बथशेबा

2
@Ayxan मैं उस मामले में अनुमान लगाऊंगा, जो 0वास्तव में कुछ अभिव्यक्ति का परिणाम है जिसे आप रनटाइम तक नहीं जान पाएंगे। चूंकि new int[0]यह सुरक्षित है, यह आपको कुछ शाखाओं / विशेष मामलों के बारे में चिंता करने से बचा सकता है। कल्पना कीजिए कि क्या मैं एक std::vectorसाथ शुरू करने के लिए गया था std::vector<int> v(0);
scohe001

जवाबों:


3
    auto a = new int[0];

[Basic.compound.3] के अनुसार , संग्रहित मूल्य aनिम्नलिखित में से एक होना चाहिए:

  1. किसी वस्तु का सूचक (प्रकार का int)
  2. एक सूचक एक वस्तु के अंत में पिछले
  3. शून्य
  4. अमान्य

हम पहली संभावना से इंकार कर सकते हैं क्योंकि intनिर्मित प्रकार की कोई वस्तु नहीं थी । तीसरी संभावना को खारिज कर दिया जाता है क्योंकि C ++ को वापस करने के लिए एक गैर-शून्य पॉइंटर की आवश्यकता होती है (देखें [basic.stc.dynamic.allocation.2] )। इस प्रकार हम दो संभावनाओं से बचे हैं: एक सूचक एक वस्तु के अंत में या एक अवैध सूचक।

मैं aएक अतीत के सूचक के रूप में देखने के लिए इच्छुक हूं, लेकिन मेरे पास निश्चित रूप से स्थापित करने के लिए एक सम्मानित संदर्भ नहीं है। (हालांकि, [basic.stc] में इसका एक मजबूत निहितार्थ है, यह देखते हुए कि आप deleteइस सूचक को कैसे देख सकते हैं ।) इसलिए मैं इस उत्तर में दोनों संभावनाओं का मनोरंजन करूंगा।

प्रतिलिपि आरंभीकरण और विलोपन के बीच, क्या आपको सूचक को पढ़ने की अनुमति है a + 1?

व्यवहार अपरिभाषित है, जैसा कि [expr.add.4] द्वारा तय किया गया है , चाहे ऊपर से जो भी संभावना लागू हो।

यदि aएक अतीत-अंत सूचक है, तो यह 0बिना तत्वों वाले किसी सरणी के सूचकांक में काल्पनिक तत्व को इंगित करने के लिए माना जाता है । पूर्णांक जोड़ना केवल तभी परिभाषित किया jजाता aहै 0≤0+j≤n, जहां nसरणी का आकार होता है। हमारे मामले में, nशून्य है, इसलिए योग a+jकेवल तब ही परिभाषित किया jजाता है 0। विशेष रूप से, जोड़ना 1अपरिभाषित है।

यदि aअमान्य है, तो हम सफाई से "अन्यथा, व्यवहार अपरिभाषित है।" (आश्चर्य की बात नहीं, जो मामले परिभाषित किए गए हैं वे केवल वैध सूचक मानों को कवर करते हैं।)

इसके अलावा, क्या भाषा कंपाइलर को सेट aकरने की अनुमति देती है nullptr?

नहीं। उपर्युक्त [basic.stc.dynamic.allocation.2] से : "यदि अनुरोध सफल होता है, तो एक बदली आवंटन फ़ंक्शन द्वारा लौटाया गया मान एक अशक्त सूचक मान है"एक फुटनोट यह भी कहता है कि सी ++ (लेकिन सी नहीं) को शून्य अनुरोध के जवाब में एक गैर-शून्य सूचक की आवश्यकता होती है।


1
यदि यह अमान्य सूचक मान था, तो आपको eel.is/c++draft/basic.stc#4
TC

@TC यह सच है, इसका दृढ़ता से अर्थ है कि यह अमान्य सूचक मान नहीं हो सकता।
JaMiT

23

संपादकीय मुद्दे 3178 के परिणामस्वरूप सीडब्ल्यूजी प्रतिक्षेपक चर्चा के अनुसार , new int[0]वर्तमान में "अतीत-अंत" सूचक मूल्य कहा जाता है

यह इस प्रकार है कि aअशक्त नहीं हो सकता है, और [expr.add] / 4a + 1 द्वारा अपरिभाषित है ।


4
"संपादकीय मुद्दे 3178 के परिणामस्वरूप सीडब्ल्यूजी प्रतिक्षेपक चर्चा के अनुसार, new int[0]वर्तमान में" अतीत-अंत "पॉइंटर मान" कहा जाता है , जो कि सटीक नहीं है। ज्यादा चर्चा नहीं हुई। एक व्यक्ति ने सुझाव दिया कि मान "एक वस्तु के अंत में सूचक अतीत" होना चाहिए, और इस कथन पर सवाल उठाया गया था क्योंकि 0तत्वों के साथ एक सरणी के मामले में , पिछले के अंत में होने वाली कोई वस्तु नहीं है।
भाषा वकील

@LanguageLawyer को कोई संदेह नहीं है कि a + 1किसी भी मामले में अपरिभाषित है, इसलिए आपकी बात केवल इस बात से संबंधित है कि क्या aअशक्त हो सकता है?
एम.एम.

अभिप्रायित शब्दार्थों के बारे में कोई असहमति प्रकट नहीं हुई, न ही कि इस श्रेणी के सूचक मानों का वर्तमान नाम इस परिदृश्य के लिए खराब है।
टीसी

@MM मुझे लगता है कि a + 1अपरिभाषित है और शायद परिणामी सूचक मान को "पॉइंटर द पास्ट द एंड" कहा जाएगा। मैं यह नहीं कह रहा कि उत्तर गलत है। यह थोड़ा सटीक नहीं है क्योंकि यह समझा जा सकता है कि आम सहमति के साथ एक लंबी चर्चा हुई थी जो यह निर्दिष्ट करती है कि परिणाम "सूचक अतीत के अंत" है जो समस्या को हल करने के लिए पर्याप्त है। "पॉइंटर पास्ट द एंड" के साथ समस्या यह है कि यह किसी ऑब्जेक्ट के अंत में होता है और 1ऐसे पॉइंटर वैल्यू से घटाकर ऑब्जेक्ट को एक पॉइंटर दिया जाता है, जो शायद 0तत्वों के सरणियों के लिए मामला नहीं होना चाहिए ।
भाषा वकील

2
@ बाथशीबा क्या आपको लगता है कि दोषपूर्ण शब्दों के बारे में अधिक आधिकारिक कुछ भी हो सकता है?
भाषा वकील
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.