2015-12-26 7 views
5

नीचे कोड का आउटपुट 2500 है। इसमें पॉइंटर्स हैं। क्या कोई इस बारे में उचित स्पष्टीकरण दे सकता है? यह 2500 के रूप में क्यों प्रिंट करता है? क्या यह सूचक घोषणा के माध्यम से आता है या कोई और कारण है?क्या यह गलत होगा? और यदि ऐसा है तो यह क्यों है? आउटपुट 2500

#include <stdio.h> 

/* Two functions include and they are operated by main function */ 

int *f(int x) { 
    /* Creates an variable */ 
    int p; 
    p = x; 
    return &p; 
} 

/* Here the initialization of the function g */ 
int *g(int x) { 
    /* Creates an variable */ 
    int y; 
    y = x; 
    return &y; 
} 

/* This creates two pointers called x and y */ 
int main() { 
    int *x, *y; 
    /* Here call the functions f and g */ 
    x = f(100); 
    /* Here call the function g */ 
    y = g(2500); 
    /* How does it print 2500? */ 
    /* print the value of x */ 
    printf("%d \n", *x); 
    return 0; 
} 
+0

'जोर दें (x == y);' –

+0

@DanLowe धन्यवाद। इसके लिए और टाइपो को ठीक करना भी :) –

+1

सभी चेतावनियों और डीबग जानकारी (उदाहरण के लिए 'gcc -Wall -Wextra -g' [GCC] (http://gcc.gnu.org/) का उपयोग करते हुए संकलित करें ...) तो ** डीबगर ** ('gdb') –

उत्तर

8

कारण आप अजीब आउटपुट प्राप्त कर रहे हैं अपरिभाषित व्यवहार है। आप स्वत: स्थानीय चर के पते को वापस कर रहे हैं जो एक बार फ़ंक्शन समाप्त होने के बाद मौजूद नहीं होगा।

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

+0

यदि मैं जी को कॉल करने के बाद f कॉल करने जैसे फ़ंक्शन कॉल को छोटा करता हूं, तो आउटपुट 100 या अन्य मान होगा? –

+0

यह संभवतः '100' होगा। लेकिन, जब यूबी है, तो सभी दांव बंद हो जाते हैं। – haccks

+0

समर्थन के लिए धन्यवाद! –

5

अपने कार्यों के दोनों में, आप समारोह में एक स्थानीय चर का पता वापस जाने के लिए प्रयास करें। एक बार जब फ़ंक्शन निष्पादन समाप्त हो जाता है और नियंत्रण कॉलर को वापस लौटाता है, तो लौटाया गया पता अमान्य हो जाता है (यानी, चर के दायरे से बाहर निकलते हैं) और लौटाए गए मान का उपयोग करने का कोई भी प्रयास undefined behavior को आमंत्रित करता है।

यदि आपको किसी फ़ंक्शन से कोई पता वापस करना है और कॉलर में इसका उपयोग करना है, तो आपको एक पॉइंटर की आवश्यकता होगी जिसे malloc() और परिवार जैसे गतिशील स्मृति आवंटक कार्यों के माध्यम से स्मृति आवंटित किया गया है।

+0

का उपयोग करें यदि मैं जी को कॉल करने के बाद f कॉल करने जैसे फ़ंक्शन कॉल को छोटा करता हूं, तो आउटपुट 100 या अन्य मान होगा? –

+0

@ थिलिना वीराज समस्या यह है कि, जब आप यूबी को मार देते हैं, कुछ भी नहीं, बिल्कुल कुछ भी गारंटी नहीं है। आपके कोड में यूबी के साथ, आप अपने कोड को कुछ भी सार्थक या सार्थक करने की उम्मीद नहीं कर सकते हैं। –

+0

हां। लेकिन आप धारणाएं कर सकते हैं और अंतिम जवाब प्राप्त कर सकते हैं। क्या मैं सही हूँ? –

2

मुझे लगता है कि क्या होता है स्टैक का उपयोग करके समझाया जा सकता है। फ़ंक्शन f को कॉल करते समय, स्टैक निम्नानुसार व्यवहार करता है। "रिट" वापसी का पता है।

2| | 2| | 2| | 2| p | 
1| | -> 1| | -> 1|ret| -> 1|ret| 
0| | 0|100| 0|100| 0|100| 

अब ढेर सूचक 2 पर है, और उस पते (पी का पता) लौट आए और मुख्य में करने के लिए * x असाइन किया गया है। जब यह एफ से वापस आता है, तो सभी स्टैक मान पॉप हो जाते हैं, लेकिन वास्तव में क्या होता है केवल स्टैक पॉइंटर के मान को कम करना। वहां धक्का देने वाले मूल्यों के लिए अभी भी वहां हैं। फिर से फ़ंक्शन जी को कॉल किया जाता है और स्टैक निम्नानुसार है।

2| p | 2| p | 2| p | 2| y | 
1|ret | -> 1|ret | -> 1|ret | -> 1|ret | 
0|100 | 0|2500| 0|2500| 0|2500| 

समारोह च के रूप में एक ही, पी के पते लौट आए और मुख्य में * y को सौंपा गया है। लेकिन ध्यान दें कि यह पी के रूप में भी वही पता है, 2. इसलिए * मुख्य रूप से एक्स और * वाई दोनों एक ही स्थान पर इंगित करते हैं। फंक्शन जी ने उस पते के मान 2500 पर सेट किए हैं, इसलिए * x और * y दोनों प्रिंट 2500.

आशा है कि इससे मदद मिलती है। :)

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