2017-11-10 17 views
6

पर डाली गई सी ++ में एक नौसिखिया के रूप में मैं पॉइंटर्स के साथ थोड़ा सा खेल रहा हूं। मैं एक पूर्णांक के रूप में एक छोटी सरणी व्याख्या करने के लिए निम्नलिखित कोड लिखा है:सी ++ लघु सरणी 'उलट' जब पूर्णांक

#include <iostream> 
int main(){ 
    short array[2] = {10, 9}; 

    short* pointer = array; 
    std::cout << pointer << ": " << *pointer << std::endl; 
    // 0xffffcbdc: 10 

    pointer++; 
    std::cout << pointer << ": " << *pointer << std::endl; 
    // 0xffffcbde: 9 

    int* pointer2 = (int*) array; 
    std::cout << pointer2 << ": " << *pointer2 << std::endl; 
    // 0xffffcbdc: 589834 
} 

क्यों है पूर्णांक 589'834 (0009 000A) के मूल्य और नहीं 655'369 (000A 0009)?

मुद्रित सूचक पते से ऐसा लगता है कि सरणी स्मृति में क्रम में है, तो पूर्णांक को कास्टिंग क्यों बदलता है?

+4

बड़े-एंडियन देखें। और थोड़ा-एंडियन। – nicomp

+0

"अपरिभाषित व्यवहार" पुलिस आज लागू है - मुझे जवाब पोस्ट करने की हिम्मत नहीं है। – nicomp

+0

सबसे पहले, हेक्स-वैल्यू के रूप में आपके पूर्णांक प्रतिनिधित्व गलत हैं: 58 9'834 == 0x0009'000A और 655'369 == 0x000A'0009। आपके इंट-पॉइंटर रूपांतरण के बावजूद व्यवहार को अपरिभाषित करने के बावजूद, आपका सीपीयू "लिटिल एंडियन" का उपयोग करता है जिसका अर्थ है कि निचले बाइट्स को कम मेमोरी पतों पर संग्रहीत किया जाता है। "बिग एंडियन" में उच्च बाइट्स कम मेमोरी पतों पर संग्रहीत होते हैं। "लिटिल एंडियन" का उपयोग करके, कोई पैडिंग और 16-बिट शॉर्ट इनट्स में आपके सरणी में स्मृति में निम्न लेआउट नहीं है: 0 ए 00 09 00. इसके बजाए "बिग एंडियन" का उपयोग करके, स्मृति 00 0 ए 00 09. – CAF

उत्तर

8

यह व्यवहार अपरिभाषित है:

int* pointer2 = (int*) array; 

आप T2 केवल तभी T2 के संरेखण आवश्यकताओं एक ही या T1 के संरेखण आवश्यकताओं की तुलना में कम सख्त हैं के सूचक के रूप T1 के लिए सूचक पुनर्व्याख्या करने की अनुमति है (see reference for more details) । चूंकि int के लिए संरेखण आवश्यकताओं short के लिए संरेखण आवश्यकताओं की तुलना में कठोर हैं, इसलिए आपका सूचक पुन: व्याख्या अमान्य है।

ध्यान दें कि short पर पॉइंटर के रूप में int पर पॉइंटर को दोबारा व्याख्या करना मान्य होगा।

नोट: चूंकि व्यवहार अपरिभाषित है, इसलिए आपका प्रोग्राम गलत मूल्य प्रिंट करने या यहां तक ​​कि क्रैश होने सहित कुछ भी कर सकता है। हालांकि, आपके द्वारा देखे जाने वाले व्यवहार के लिए सबसे संभावित कारण यह है कि आपका सिस्टम निचले पते पर पूर्णांक के उच्च बाइट स्टोर करता है। यह दो सामान्य विकल्पों में से एक है: दूसरा एक उच्च पते पर उच्च बाइट स्टोर करना है। इन दो विकल्पों को एंडियननेस कहा जाता है। More information on it is here.

+1

"ध्यान दें कि एक सूचक के रूप में int को एक पॉइंटर को फिर से व्याख्या करना वैध होगा।" मैं जोड़ना चाहता हूं, कि आप सख्त एलियासिंग नियमों के कारण सूचक को अस्वीकार नहीं कर सकते हैं। –

3

आप जो भी करते हैं वह अनिर्धारित व्यवहार है, क्योंकि आप सख्त एलियासिंग नियम का उल्लंघन कर रहे हैं। इसलिए, इससे प्राप्त किसी भी आउटपुट के बारे में परेशान न हों।

+0

जैसा दिखता है यदि यह अपरिभाषित नहीं है समझें कि पूर्णांक कैसे संग्रहीत किए जाते हैं। यह स्रोत कोड स्तर पर अपरिभाषित है लेकिन CPU स्तर पर निर्धारक है। – nicomp

+4

@nicomp यह अनिश्चित है, इस अर्थ में कि संकलक को कोड के साथ कुछ भी करने की अनुमति है। यदि कोड किसी भी परिणाम का उत्पादन करता है तो यह पूरी तरह से संयोग है और संकलक के संस्करणों के बीच या प्रोग्राम के आविष्कार के बीच भी बदल सकता है। – Johan

+0

यदि आप मानते हैं कि कोई कंपाइलर अनुकूलन नहीं होता है, तो यह केवल निर्धारक है, और आपका कंपाइलर उद्देश्य पर माध्य का प्रयास नहीं कर रहा है। यूबी परिभाषा द्वारा निर्धारित नहीं है। – Treeston

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