2010-12-27 14 views
12

उदाहरण कोड:क्या यह एक पॉइंटर को चर के बाहर एक चर रखने के लिए सुरक्षित है?

#include <stdio.h> 
int main(){ 
    int *p; 
    { 
     int v = 1; 
     p = &v; 
    } 
    printf("%d\n", *p); 
    return 0; 
} 

इस कोड को ठीक काम करता है, लेकिन मुझे यकीन है कि एक गारंटी नहीं है कि वी के पते को संरक्षित किया जाएगा मौजूद है या नहीं हूँ।

उत्तर

24

कोई गारंटी नहीं है।

एक बार v गुंजाइश से बाहर हो जाता है, इसके साथ कुछ भी कर रहा है (यहां तक ​​कि एक सूचक के माध्यम से) Undefined Behavior माना जाता है।

किसी अन्य अपरिभाषित व्यवहार के साथ, क्योंकि यह एक ऑपरेटिंग सिस्टम, कंपाइलर, कंपाइलर संस्करण, दिन का समय इत्यादि पर काम करता है, इसका मतलब यह नहीं है कि यह दूसरे के लिए काम करेगा।

+3

इस विशेष मामले में, आप संकलक अनुकूलन सेटिंग्स के आधार पर व्यवहार में मतभेदों को भी देख सकते हैं। फिर, पत्थर में कुछ भी सेट नहीं है, क्योंकि सी मानक परिभाषित नहीं करता है कि क्या होने वाला है, यहां। –

8

Merlyn के जवाब पर जोड़ने के लिए, एक मामले में जहां यह शायद व्यवहार आप का इरादा नहीं था में परिणाम होगा है निम्नलिखित:

#include <stdio.h> 
int main(){ 
    int *p; 
    { 
     int v = 1; 
     p = &v; 
    } 
    { 
     int w = 2; 
     printf("%d\n", w); 
    } 
    printf("%d\n", *p); 
    return 0; 
} 

संकलक होने v और w शेयर पर एक ही आवंटन कर इस का अनुकूलन कर सकते हैं ढेर। फिर, कंपाइलर भी इसे अनुकूलित नहीं कर सकता है - यही कारण है कि उनके संलग्न ब्लॉक सिरों के बाद पॉइंटर्स को चर का उपयोग करने का व्यवहार परिभाषित नहीं किया गया है। प्रोग्राम "2" और "1", या "2" और "2", या "2" आउटपुट और कुछ संकलक और सेटिंग्स का उपयोग करने के आधार पर कुछ अलग हो सकता है।

+3

आपका अंतिम अनुच्छेद गलत है। प्रति सी 99 §6.8.5.3, "यदि क्लॉज -1 घोषणा है, तो घोषित किसी भी पहचानकर्ता का दायरा घोषणा का शेष है और पूरे लूप, जिसमें अन्य दो अभिव्यक्तियां शामिल हैं" यह * नहीं * के लिए दायरे में है मुख्य शेष –

+1

@ मैथ्यू: क्या आप निश्चित हैं कि जीवनकाल को संदर्भित करता है न कि सिर्फ व्याख्यात्मक दायरे? – cdhowie

+1

मेरा मानना ​​है कि यह दोनों है। फुटनोट कहता है, "इस प्रकार, लूप के लिए क्लॉज -1 विशिष्टता प्रारंभिक रूप से, लूप ** में उपयोग के लिए संभवतः एक या अधिक चर घोषित ** ** (जोर जोड़ा गया)। सी ++ मानक (§6.5.3) इसे और अधिक स्पष्ट रूप से समझाता है (लेकिन मैं समकक्ष मानता हूं), यह दिखाता है कि एक अनुरूपित ब्लॉक कैसे बनाया जाता है। –

0

फिर यह कभी कभी काम करेंगे, लेकिन एक यकीन है कि यह काम करता है नहीं हो सकता है ... यह कभी कभी न केवल बस त्रुटि होती है लेकिन फिर भी पूरे कार्यक्रम दुर्घटना का कारण कर सकते हैं ...

मैं यू एक उदाहरण दे देंगे

इस पर एक नज़र डालें .. http://www.functionx.com/cpp/examples/returnreference.htm

यहाँ

वह एक चर जो क्षेत्र से बाहर चला जाता है के संदर्भ वापस जाने के लिए कोशिश कर रहा है ... (बिग गलती) ..लेकिन यह काम करता है ....

आप गारंटी नहीं दे सकते .. इसलिए यह बेहतर है (बेहतर नहीं है) कभी भी डेटा के संदर्भ में वापस लौटने के लिए नहीं है

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