2010-04-30 26 views
5
int* test() 
{ 
    int a = 5; 
    int* b = &a; 
    return b; 
} 

test का परिणाम bad pointer होगा? जहां तक ​​मुझे पता है कि हटाया जाना चाहिए और फिर b एक गड़बड़ कर सूचक बन जाएगा, है ना?सी ++: पॉइंटर्स और स्कोप

अधिक जटिल चीजों के बारे में, एक इंट पॉइंटर नहीं, लेकिन 20 सदस्यों के साथ कक्षा के साथ ही?

+2

यहां कोई कचरा संग्रह नहीं है। बस अवांछित ढेर। – Tom

उत्तर

7

जो आप लौट रहे हैं उसके लिए शब्द "dangling pointer" है। a स्टैक पर आवंटित एक स्थानीय चर है, और यह स्कोप से बाहर होने के बाद उपलब्ध नहीं है (जो कि कचरा संग्रह से पूरी तरह से अलग है)। test() पर कॉल के परिणाम का उपयोग करने का प्रयास अपरिभाषित व्यवहार होगा।

दूसरी ओर, यदि आप a ढेर पर आवंटित नहीं किया - (int *a = new int(5);), तो int *b = a; return b; हालांकि नहीं के रूप में अच्छा के रूप में return new int(5) ठीक हो सकता है,। हालांकि, यदि आप बाद में परिणाम free सही नहीं करते हैं, तो आपके पास मेमोरी रिसाव होगा।

+0

ठीक है - और इसे हल करने का कोई तरीका है?मूल्य बनाए रखने के लिए मुझे इसे कहीं और परिभाषित करने की आवश्यकता नहीं है? –

+0

आपका लक्ष्य वास्तव में क्या है? प्रत्येक बार 'test()' कहा जाता है, उसी वस्तु पर एक सूचक को लौटाना? उदाहरण के लिए, आप स्थिर चर का पता वापस कर सकते हैं। –

5

हां, यह किसी ऐसे सूचक के लिए सूचक है जो अब मौजूद नहीं है, स्थानीय चर को एक कहा जाता है। चाहे एक int, एक सरणी है, कक्षा का एक उदाहरण कोई फर्क नहीं पड़ता। और सी ++ में कचरा संग्रह नहीं है।

int test() 
{ 
    int a = 5; 
    return a; 
} 

यह कक्षाओं के लिए सच के साथ ही प्रकार में निर्मित है:

इस मामले में, और कई अन्य लोगों में, आप निश्चित रूप से एक प्रति लौटना चाहिए।

2

इस मामले में सूचक b स्टैक से आवंटित एक इकाई को इंगित करता है। जैसे ही यह फ़ंक्शन लौटाता है, वह स्मृति कॉलिंग प्रक्रिया के लिए उपलब्ध होगी।

आप एक वस्तु है कि प्रक्रिया है जो उसे बनाया से अधिक जीवित होगा बनाने की जरूरत है, तो आप malloc() या new का उपयोग ढेर से स्मृति का एक ब्लॉक पाने के लिए, और free या यह delete बाद में करने के लिए याद करने के लिए की आवश्यकता होगी।

0

हां, यह एक खतरनाक सूचक देगा। यदि आप मूल्य को जारी रखना चाहते हैं, तो आपके पास कुछ संभावनाएं हैं। एक यह है कि चूंकि आप स्पष्ट रूप से वास्तव में एक मूल्य वापस करना चाहते हैं, वही करें - एक सूचक के बजाय मूल्य वापस करें। दूसरा एक नया ऑब्जेक्ट आवंटित करना है, और उस गतिशील आवंटित स्थान पर एक सूचक वापस कर देना है। यह ऑब्जेक्ट को कॉलर की ज़िम्मेदारी को हटा देता है, हालांकि, जो मेमोरी लीक और इस तरह के कारण हो सकता है।

अंत में, आप आम तौर पर यह पता लगाना चाहते हैं कि वेरिएबल वास्तव में किस स्कोप की ज़रूरत है, और उसके पास उस स्कोप के साथ कुछ (अक्सर एक ऑब्जेक्ट) स्वामित्व है, इसलिए इसे स्वचालित रूप से दायरे में प्रवेश पर बनाया जाएगा, और दायरे से बाहर निकलने पर स्वचालित रूप से नष्ट कर दिया।

यदि आप ऐसा नहीं कर सकते हैं, तो आपको अभी भी यह पता लगाना होगा कि वस्तु का "मालिक" कौन है, और आवश्यकतानुसार इसे नष्ट करने के लिए जिम्मेदार होगा। एक बार थोड़ी देर में पिन करना मुश्किल होता है, और चीजों का ट्रैक रखने के लिए आपको संदर्भ-गणना वाले पॉइंटर की तरह कुछ चाहिए। कम से कम मेरे अनुभव में, इनका उपयोग वास्तव में अक्सर होने के मुकाबले कहीं अधिक होता है। मैं सी ++ को तब तक लिख रहा हूं जब तक कि एटी & टी के बाहर कोई भी व्यक्ति नहीं है, और अभी तक एक साझा_प्टर की आवश्यकता नहीं है। कुछ बार, मैंने सोचा है कि मुझे इसकी आवश्यकता होगी, लेकिन आखिर में एक क्लीनर डिज़ाइन की आवश्यकता को समाप्त कर दिया गया।

+0

आप साझा पॉइंटर्स को पुराने सिस्टम पर ले जा सकते हैं जो अप्रत्याशित चीजें कर सकते हैं, और जिन्हें आप फिर से डिज़ाइन नहीं करना चाहते हैं, और सुरक्षा की एक बड़ी मात्रा प्राप्त कर सकते हैं। इसके अलावा, उन्हें संशोधन के वर्षों में सही रखना आसान है। –

+0

@ डेविड: ओह, काफी सच - मेरा मतलब यह नहीं था कि वे बेकार थे, या ऐसा कुछ भी। साथ ही, मैं उनके बारे में सोचता हूं कि कोड को वास्तव में कैसे लिखा जाना चाहिए, इस बारे में बैंड-एड्स के अधिक से अधिक। हालांकि, कोई सवाल नहीं है कि अगर आपके पास कोड "खून बह रहा" कोड है, तो बैंड-सहायता बेहद उपयोगी हो सकती है ... –

+0

वे मूल रूप से कचरा संग्रह हैं, जो काफी प्राचीन और विकेन्द्रीकृत प्रकार के हैं। जहां भी कचरा संग्रह होता है, वे बड़े होते हैं, और बड़े वास्तविक जीवन प्रणालियों के लिए मैं पिछले दस वर्षों में इस पर काम करने वाले प्रत्येक डेवलपर की तुलना में जीसी पर निर्भर करता हूं। –

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