2010-10-24 13 views
33

मैं सी के लिए एक पूर्ण नौसिखिया हूं, और मेरे विश्वविद्यालय के काम के दौरान मैं कोड में टिप्पणियों में आया हूं जो प्रायः एक पूर्ण सूचक को डी-रेफरेंसिंग का संदर्भ देता है। मेरे पास सी # में पृष्ठभूमि है, मुझे यह पता चल रहा है कि यह "NullReferenceException" जैसा हो सकता है जो आपको नेट में मिलता है, लेकिन अब मुझे गंभीर संदेह है।"एक पूर्ण सूचक का डी-रेफरेंसिंग" का क्या अर्थ है?

क्या कोई मुझे लेमन शब्दों में बता सकता है कि यह वास्तव में क्या है और यह बुरा क्यों है?

+0

ऐसा करने में ध्यान रखें, अपरिभाषित व्यवहार में परिणाम। आपको सी या सी ++ में अपवाद या कुछ भी नहीं मिलता है। – GManNickG

+0

आप कुछ उदाहरण कोड डालना चाहते हैं। ऐसा लगता है कि लोग (मेरे साथ) जो आप पूछने की कोशिश कर रहे हैं वह नहीं मिलता है। –

+0

कोड की कोई आवश्यकता नहीं है (कोई भी नहीं है) - यह एक वैचारिक समस्या है जो मैं कर रहा हूं, "dereferencing" की शब्दावली के आसपास अपना सिर पाने की कोशिश कर रहा हूं और मुझे इसकी देखभाल क्यों करनी चाहिए। – Ash

उत्तर

47

स्मृति जो मौजूद नहीं है के लिए एक NULL सूचक अंक। यह पता 0x00000000 या कोई अन्य कार्यान्वयन-परिभाषित मान हो सकता है (जब तक यह वास्तविक पता कभी नहीं हो सकता)। इसका मतलब है कि पॉइंटर द्वारा जो भी इंगित किया गया है उसे एक्सेस करने का प्रयास करना।

int a, b, c; // some integers 
int *pi;  // a pointer to an integer 

a = 5; 
pi = &a; // pi points to a 
b = *pi; // b is now 5 
pi = NULL; 
c = *pi; // this is a NULL pointer dereference 

यह ठीक, सी # में एक NullReferenceException के समान है, सिवाय इसके कि सी में संकेत दिए गए, किसी भी डेटा वस्तु को इंगित कर सकते हैं एक सरणी के अंदर भी तत्व: * ऑपरेटर dereferencing ऑपरेटर है।

+8

@Ash: एक पॉइंटर में एक स्मृति पता होता है जो * संदर्भ * कुछ के लिए होता है। उस स्मृति पते से उस * संदर्भित * तक पहुंचने के लिए, आपको स्मृति पता * डी-रेफरेंस * करना होगा। –

+0

@Ash, जो सिलिको में कहा गया था, लेकिन जब आप स्मृति पते पर संग्रहीत मान प्राप्त करते हैं तो आपको संदर्भित करते हैं। कोशिश करो। Int पी करो; printf ("% p \ n", &p); इसे एक पता मुद्रित करना चाहिए। जब ​​आप पता लगाने के लिए पॉइंटर (* var) नहीं बनाते हैं, तो आप जिस पते का उपयोग करते हैं उसे प्राप्त करने के लिए और var – Matt

+0

@Greg जब आप 'char * foo = NULL' और फिर उपयोग करें और foo? – Bionix1441

-1

wiki

से एक नल पॉइंटर जरूरी मान शून्य एक आरक्षित मूल्य है, अक्सर नहीं बल्कि, यह दर्शाता है कि यह कोई वस्तु
को संदर्भित करता है ..

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

int val =1; 
int *p = NULL; 
*p = val; // Whooosh!!!! 
+0

आपके उत्तर के लिए धन्यवाद, मैं एक पूर्ण सूचक क्या था, ठीक है, मुझे बस इस बारे में निश्चित नहीं था कि "dereferencing" चीजों की योजना में कैसे फिट बैठता है । – Ash

2

इसका मतलब है

myclass *p = NULL; 
*p = ...; // illegal: dereferencing NULL pointer 
... = *p; // illegal: dereferencing NULL pointer 
p->meth(); // illegal: equivalent to (*p).meth(), which is dereferencing NULL pointer 

myclass *p = /* some legal, non-NULL pointer */; 
*p = ...; // Ok 
... = *p; // Ok 
p->meth(); // Ok, if myclass::meth() exists 

मूल रूप से, लगभग (*p) या परोक्ष शामिल (*p), उदा से जुड़े कुछ भी p->... जो (*p). ... के लिए एक शॉर्टेंड है; सूचक घोषणा के अलावा।

+0

उन्होंने अपने प्रश्न को सी ++ – GWW

+2

@GWW के रूप में टैग किया: और सी और सी ++ में यह वही अर्थपूर्ण है, सिवाय इसके कि सी में कॉस्टम क्लास नहीं है। –

+0

'p-> मेथ()' '(* p) .meth()' के लिए सिर्फ एक शॉर्टेंड नहीं है, बाद में सी और सी ++ दोनों में उपलब्ध है? – Arun

0

wikipedia से हवाला देते हुए:

एक संकेतक स्मृति में एक स्थान का संदर्भ है, और स्थान पर मूल्य प्राप्त करने के एक सूचक लिए जाना जाता है रूप सूचक dereferencing संदर्भित करता है।

संकेतक unary * ऑपरेटर को पॉइंटर पर लागू करके किया जाता है।

int x = 5; 
int * p;  // pointer declaration 
p = &x;  // pointer assignment 
*p = 7;  // pointer dereferencing, example 1 
int y = *p; // pointer dereferencing, example 2 

"एक शून्य सूचक dereferencing" *p प्रदर्शन का मतलब है जब pNULL

20

अपसंदर्भन सिर्फ एक दिए गए पते पर स्मृति मूल्य पढ़ने का मतलब है। तो जब आपके पास कुछ करने के लिए पॉइंटर होता है, तो को संदर्भित करें पॉइंटर का मतलब है कि पॉइंटर इंगित करने वाले डेटा को पढ़ने या लिखना है।

सी में, unary * ऑपरेटर dereferencing ऑपरेटर है।यदि x एक सूचक है, तो *xx अंक है। यूनरी & ऑपरेटर पता ऑपरेटर है। यदि x कुछ भी है, तो &x वह पता है जिस पर x स्मृति में संग्रहीत है। * और & ऑपरेटरों एक दूसरे के प्रतिलोम हैं: अगर x किसी भी डेटा है, और y किसी भी सूचक है, तो इन समीकरणों हमेशा सच हैं:

*(&x) == x 
&(*y) == y 

एक नल पॉइंटर एक सूचक है कि किसी भी वैध को इंगित नहीं करता है डेटा (लेकिन यह एकमात्र ऐसा सूचक नहीं है)। सी मानक कहता है कि यह अपरिभाषित व्यवहार एक शून्य सूचक को कम करने के लिए है। इसका मतलब है कि बिल्कुल कुछ भी हो सकता है: प्रोग्राम क्रैश हो सकता है, यह चुपचाप काम करना जारी रख सकता है, या यह आपकी हार्ड ड्राइव मिटा सकता है (हालांकि यह असंभव है)।

अधिकांश कार्यान्वयन में, आपको ऐसा करने का प्रयास करने पर "सेगमेंटेशन गलती" या "एक्सेस उल्लंघन" मिलेगा, जो लगभग हमेशा आपके प्रोग्राम को ऑपरेटिंग सिस्टम द्वारा समाप्त कर दिया जाएगा। यहाँ एक तरह से एक अशक्त सूचक dereferenced जा सकता है:

int *x = NULL; // x is a null pointer 
int y = *x;  // CRASH: dereference x, trying to read it 
*x = 0;   // CRASH: dereference x, trying to write it 

और हाँ, एक अशक्त सूचक dereferencing काफी वास्तव में सी # में एक NullReferenceException (या जावा में एक NullPointerException) की तरह है, सिवाय इसके कि भाषा के मानक एक छोटे से अधिक है यहां सहायक सी # में, एक शून्य संदर्भ को संदर्भित करने के लिए अच्छी तरह से परिभाषित व्यवहार है: यह हमेशा NullReferenceException फेंकता है। ऐसा कोई तरीका नहीं है कि आपका प्रोग्राम चुपचाप काम करना जारी रख सके या सी में अपनी हार्ड ड्राइव मिटा दें (जब तक कि भाषा रनटाइम में कोई बग न हो, लेकिन फिर भी यह अविश्वसनीय रूप से असंभव है)।

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