Dangling pointer in C in Hindi
Pointers और स्मृति प्रबंधन से संबंधित सबसे आम bugs dangling/wild pointers हैं। कभी-कभी प्रोग्रामर पॉइंटर को एक वैध पते के साथ आरंभ करने में विफल रहता है, तो इस प्रकार के इनिशियलाइज्ड पॉइंटर को सी में dangling वाले pointer के रूप में जाना जाता है।
ऑब्जेक्ट के नष्ट होने के समय dangling पॉइंटर तब होता है जब पॉइंटर को हटा दिया जाता है या पॉइंटर के मूल्य को modify किए बिना मेमोरी से de-allocate किया जाता है। इस मामले में, सूचक मेमोरी की ओर इशारा करता है, जिसे de-allocate किया जाता है। dangling पॉइंटर मेमोरी को इंगित कर सकता है, जिसमें प्रोग्राम कोड या ऑपरेटिंग सिस्टम का कोड होता है। यदि हम इस सूचक को मान प्रदान करते हैं, तो यह प्रोग्राम कोड या ऑपरेटिंग सिस्टम निर्देशों के मूल्य को overwrite करता है; ऐसे मामलों में, कार्यक्रम undesirable result दिखाएगा या crash भी हो सकता है। यदि मेमोरी को किसी अन्य प्रक्रिया में फिर से आवंटित किया जाता है, तो हम dangling पॉइंटर को रोकते हैं जिससे विभाजन दोष उत्पन्न हो जाएगा।
आइए निम्नलिखित उदाहरण देखें।
उपरोक्त आकृति में, हम देख सकते हैं कि pointer 3 एक dangling वाला सूचक है। pointer 1 और pointer 2 पॉइंटर्स हैं जो आवंटित ऑब्जेक्ट्स को point करते हैं, अर्थात, क्रमशः ऑब्जेक्ट 1 और ऑब्जेक्ट 2. pointer 3 एक dangling सूचक है क्योंकि यह de-allocated ऑब्जेक्ट को point करता है।
आइए कुछ C कार्यक्रमों के माध्यम से dangling पॉइंटर को समझें।
मेमोरी को de-allocate करने के लिए free() फ़ंक्शन का उपयोग करना।
- #include <stdio.h>
- int main()
- {
- int *ptr=(int *)malloc(sizeof(int));
- int a=560;
- ptr=&a;
- free(ptr);
- return 0;
- }
उपरोक्त कोड में, हमने दो variable बनाए हैं, अर्थात, *ptr और जहाँ ‘ptr’ एक पॉइंटर है और ‘a’ integer variable है। * Ptr एक पॉइंटर वैरिएबल है जो कि malloc() फंक्शन की मदद से बनाया जाता है । जैसा कि हम जानते हैं कि malloc() फ़ंक्शन शून्य देता है, इसलिए हम void पॉइंटर को int पॉइंटर में बदलने के लिए int * का उपयोग करते हैं।
Statement int*ptr=(int *) malloc(sizeof(int)); नीचे दी गई छवि में दिखाए गए 4 bytes के साथ मेमोरी आवंटित करेंगे:
स्टेटमेंट free(ptr) de-allocate को cross sign के साथ नीचे की छवि में दिखाया गया है, और ‘ptr’ पॉइंटर झूलता हुआ हो जाता है क्योंकि यह de-allocate मेमोरी की ओर point करता है।
यदि हम ‘ptr’ को NULL मान देते हैं, तो ‘ptr’ डिलीट की गई मेमोरी को point नहीं करेगा। इसलिए, हम कह सकते हैं कि ptr एक dangling सूचक नहीं है, जैसा कि नीचे दी गई छवि में दिखाया गया है:
Variable goes out of the scope
जब variable दायरे से बाहर हो जाता है तो variable की ओर इशारा करने वाला सूचक dangling सूचक बन जाता है ।
- #include<stdio.h>
- int main()
- {
- char *str;
- {
- char a = ?A?;
- str = &a;
- }
- // a falls out of scope
- // str is now a dangling pointer
- printf(“%s”, *str);
- }
In the above code, we did the following steps:
- सबसे पहले, हम पॉइंटर वैरिएबल को ‘str’ नाम देते हैं।
- आंतरिक दायरे में, हम एक character variable घोषित करते हैं। Str पॉइंटर में वेरिएबल ‘a’ का address होता है।
- जब नियंत्रण आंतरिक दायरे से बाहर आता है, तो ‘a’ वैरिएबल अब उपलब्ध नहीं होगा, इसलिए de-allocated मेमोरी को string इंगित करता है। इसका मतलब है कि str पॉइंटर dangling वाला पॉइंटर बन जाता है।
Function call
अब, हम देखेंगे कि जब हम फ़ंक्शन को कॉल करते हैं तो पॉइंटर कैसे dangling बनता है।
आइए एक उदाहरण के माध्यम से समझते हैं।
- #include <stdio.h>
- int *fun(){
- int y=10;
- return &y;
- }
- int main()
- {
- int *p=fun();
- printf(“%d”, *p);
- return 0;
- }
उपरोक्त कोड में, हमने निम्नलिखित कदम उठाए:
- सबसे पहले, हम main() फ़ंक्शन बनाते हैं, जिसमें हमने ‘p’ पॉइंटर घोषित किया है जिसमें fun() का रिटर्न वैल्यू है ।
- जब fun() कहा जाता है, तो के संदर्भ के लिए नियंत्रण चाल int*fun(), fun() ‘y’ variable का पता देता है।
- जब नियंत्रण main() फ़ंक्शन के संदर्भ में वापस आता है , तो इसका मतलब है कि variable ‘y’ अब उपलब्ध नहीं है। इसलिए, हम कह सकते हैं कि ‘p’ पॉइंटर एक dangling पॉइंटर है क्योंकि यह de-allocated मेमोरी की ओर pointer करता है।
Output
आइए ऊपर दिए गए कोड के कार्य को diagrammatically रूप से दर्शाते हैं।
आइए एक dangling वाले pointer का एक और उदाहरण देखें।
- #include <stdio.h>
- int *fun()
- {
- static int y=10;
- return &y;
- }
- int main()
- {
- int *p=fun();
- printf(“%d”, *p);
- return 0;
- }
उपरोक्त कोड पिछले एक के समान है लेकिन एकमात्र अंतर यह है कि variable ‘y’ static है। हम जानते हैं कि global मेमोरी में static वेरिएबल स्टोर हैं।
Output
अब, हम उपर्युक्त कोड के आरेख के कार्य का प्रतिनिधित्व करते हैं।
उपरोक्त diagram स्टैक मेमोरी को दर्शाता है। सबसे पहले, the fun() फ़ंक्शन को कहा जाता है, फिर नियंत्रण int *fun() के संदर्भ में चलता है । चूंकि ‘y’ एक static वैरिएबल है, इसलिए यह वैश्विक मेमोरी में स्टोर होता है; इसका दायरा पूरे program में उपलब्ध है। जब address value वापस किया जाता है, तो नियंत्रण main() के संदर्भ में वापस आता है । सूचक ‘p’ में ‘y’ का पता होता है, अर्थात, 100। जब हम ‘* p’ के मान को प्रिंट करते हैं, तो यह ‘y’ के मान को प्रिंट करता है, अर्थात 10., इसलिए हम कह सकते हैं कि pointer ‘p’ एक dangling सूचक नहीं है क्योंकि इसमें वैरिएबल का address होता है जिसे global मेमोरी में संग्रहीत किया जाता है।
Avoiding Dangling Pointer Errors
NULL मान के लिए सूचक को प्रारंभ करने से dangling पॉइंटर error को टाला जा सकता है । यदि हम पॉइंटर को NULL मान देते हैं , तो पॉइंटर de-allocate मेमोरी को point नहीं करेगा। सूचक को NULL मान निर्दिष्ट करने का अर्थ है कि सूचक किसी भी मेमोरी स्थान की ओर point नहीं कर रहा है।