अध्याय 10: C++ पॉइंटर्स और एर्रे (C++ Pointers and Arrays)

अध्याय 10: C++ पॉइंटर्स और एर्रे (C++ Pointers and Arrays)

C++ प्रोग्रामिंग में, पॉइंटर्स और एर्रे के बीच का संबंध एक महत्वपूर्ण और बुनियादी अवधारणा है। एर्रे के तत्वों के साथ काम करने के लिए पॉइंटर्स का उपयोग करने से न केवल कोड को अधिक कुशल और लचीला बनाया जा सकता है, बल्कि यह मेमोरी को भी बेहतर तरीके से प्रबंधित करने में मदद करता है। इस अध्याय में, हम समझेंगे कि पॉइंटर्स और एर्रे के बीच कैसे घनिष्ठ संबंध होता है और कैसे आप पॉइंटर्स का उपयोग करके एर्रे के तत्वों तक पहुँच सकते हैं, उन्हें संशोधित कर सकते हैं, और उन पर गणनाएँ कर सकते हैं। हम यह भी देखेंगे कि कैसे पॉइंटर अरिथमेटिक के माध्यम से एर्रे को अधिक प्रभावी ढंग से प्रबंधित किया जा सकता है। इस अध्याय के अंत तक, आप पॉइंटर्स और एर्रे के बीच के संबंध को समझकर C++ में अधिक उन्नत और कुशल प्रोग्रामिंग तकनीकों का उपयोग करने में सक्षम होंगे।

एर्रे और पॉइंटर्स का परिचय (Introduction to Arrays and Pointers)

C++ प्रोग्रामिंग में एर्रे और पॉइंटर्स के बीच एक महत्वपूर्ण और घनिष्ठ संबंध होता है। एर्रे डेटा का एक क्रमबद्ध संग्रह होता है, जिसमें सभी तत्व एक ही प्रकार के होते हैं, और उन्हें इंडेक्स का उपयोग करके एक्सेस किया जाता है। पॉइंटर्स, दूसरी ओर, वेरिएबल्स के मेमोरी एड्रेस को स्टोर करने के लिए उपयोग किए जाते हैं। जब आप एर्रे और पॉइंटर्स को एक साथ उपयोग करते हैं, तो आप न केवल एर्रे के तत्वों को कुशलतापूर्वक एक्सेस कर सकते हैं, बल्कि मेमोरी के साथ भी अधिक लचीले ढंग से काम कर सकते हैं।

एर्रे और पॉइंटर्स के बीच संबंध

जब आप एक एर्रे को किसी पॉइंटर के रूप में उपयोग करते हैं, तो एर्रे का नाम खुद-ब-खुद पहले एलिमेंट के मेमोरी एड्रेस की ओर इशारा करता है। इसे निम्नलिखित तरीके से समझा जा सकता है:

int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;  // 'arr' का मतलब है 'arr[0]' का एड्रेस, इसलिए 'p' में arr[0] का एड्रेस स्टोर होगा।

इस उदाहरण में, arr नामक एर्रे के पहले एलिमेंट arr[0] का एड्रेस p पॉइंटर में स्टोर किया गया है। इस प्रकार, p अब arr एर्रे के पहले एलिमेंट की ओर इशारा कर रहा है, और आप पॉइंटर का उपयोग करके एर्रे के अन्य तत्वों तक पहुँच सकते हैं।

पॉइंटर और एर्रे के साथ काम करना

पॉइंटर का उपयोग करके, आप एर्रे के किसी भी एलिमेंट तक आसानी से पहुँच सकते हैं। उदाहरण के लिए:

cout << *p;       // यह arr[0] का मान प्रदर्शित करेगा।
cout << *(p+1);   // यह arr[1] का मान प्रदर्शित करेगा।
cout << *(p+2);   // यह arr[2] का मान प्रदर्शित करेगा।

यहाँ, p+1 का अर्थ है कि पॉइंटर p को एक स्थान आगे बढ़ाया गया है, यानी वह अब arr[1] के एड्रेस पर है। इसी तरह, p+2 का अर्थ है कि पॉइंटर p को दो स्थान आगे बढ़ाया गया है, यानी वह अब arr[2] के एड्रेस पर है।

एर्रे का नाम और पहला एलिमेंट

जब आप एर्रे के नाम का उपयोग करते हैं, तो यह वास्तव में पहले एलिमेंट के एड्रेस की ओर इशारा करता है। इसे निम्नलिखित तरीके से समझा जा सकता है:

int arr[5] = {10, 20, 30, 40, 50};

cout << arr;        // यह arr[0] का एड्रेस प्रदर्शित करेगा।
cout << &arr[0];    // यह भी arr[0] का एड्रेस प्रदर्शित करेगा।
cout << *arr;       // यह arr[0] का मान प्रदर्शित करेगा।

मल्टीडायमेंशनल एर्रे और पॉइंटर्स (Multidimensional Arrays and Pointers)

C++ में मल्टीडायमेंशनल एर्रे, जैसे कि 2D या 3D एर्रे, डेटा को अधिक संगठित तरीके से संग्रहीत और प्रबंधित करने का एक तरीका प्रदान करते हैं। पॉइंटर्स का उपयोग मल्टीडायमेंशनल एर्रे के साथ करना न केवल मेमोरी को कुशलतापूर्वक प्रबंधित करने में सहायक होता है, बल्कि जटिल डेटा संरचनाओं के साथ भी प्रभावी ढंग से काम करने में मदद करता है। इस अनुभाग में, हम समझेंगे कि मल्टीडायमेंशनल एर्रे और पॉइंटर्स के बीच संबंध क्या है और कैसे आप इनका उपयोग करके एर्रे के तत्वों तक पहुँच सकते हैं।

मल्टीडायमेंशनल एर्रे का परिचय (Introduction to Multidimensional Arrays)

मल्टीडायमेंशनल एर्रे, जैसे कि 2D एर्रे, को पंक्तियों और स्तंभों (rows and columns) में व्यवस्थित किया जाता है। उदाहरण के लिए, एक 2D एर्रे को एक मैट्रिक्स के रूप में देखा जा सकता है:

int matrix[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

इस उदाहरण में, matrix एक 3×4 का 2D एर्रे है, जिसमें 3 पंक्तियाँ और 4 स्तंभ हैं।

मल्टीडायमेंशनल एर्रे और पॉइंटर्स का संबंध (Relationship Between Multidimensional Arrays and Pointers)

2D एर्रे को एक पॉइंटर-टू-पॉइंटर (pointer to pointer) के रूप में समझा जा सकता है। एक 2D एर्रे के पहले एलिमेंट का एड्रेस matrix पॉइंटर द्वारा इंगित किया जाता है। प्रत्येक पंक्ति एक 1D एर्रे के रूप में मानी जा सकती है, और हर पंक्ति का पहला एलिमेंट एक पॉइंटर द्वारा इंगित किया जाता है।

उदाहरण:

int matrix[3][4];

int (*p)[4] = matrix;  // p एक पॉइंटर है जो 4-एलिमेंट वाले एर्रे की ओर इशारा करता है।

इस उदाहरण में, p एक पॉइंटर है जो matrix की प्रत्येक पंक्ति की ओर इशारा करता है। इसका मतलब है कि p हर बार 4-एलिमेंट वाले एर्रे की ओर इशारा करेगा, जो कि matrix की प्रत्येक पंक्ति है।

मल्टीडायमेंशनल एर्रे के तत्वों तक पॉइंटर से पहुँचना (Accessing Elements of Multidimensional Array Using Pointers)

आप पॉइंटर अरिथमेटिक का उपयोग करके 2D एर्रे के किसी भी एलिमेंट तक पहुँच सकते हैं।

उदाहरण:

#include <iostream>
using namespace std;

int main() {
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };

    int (*p)[4] = matrix;

    cout << "Element at [0][0]: " << *(*(p + 0) + 0) << endl;  // 1
    cout << "Element at [1][2]: " << *(*(p + 1) + 2) << endl;  // 7
    cout << "Element at [2][3]: " << *(*(p + 2) + 3) << endl;  // 12

    return 0;
}

यहाँ, p + i का मतलब है कि पॉइंटर p को i पंक्तियों के आगे बढ़ाया जा रहा है। इसके बाद *(p + i) पंक्ति के पहले एलिमेंट की ओर इशारा करेगा। फिर, *(p + i) + j स्तंभ j की ओर इशारा करेगा, और *(*(p + i) + j) उस तत्व का मान देगा।

थ्री-डायमेंशनल एर्रे और पॉइंटर्स (Three-Dimensional Arrays and Pointers)

यदि आपके पास एक 3D एर्रे है, तो इसे भी पॉइंटर के माध्यम से एक्सेस किया जा सकता है। उदाहरण के लिए:

int arr[2][3][4];

int (*p)[3][4] = arr;  // p एक पॉइंटर है जो 3x4 के 2D एर्रे की ओर इशारा करता है।

यहाँ, p एक पॉइंटर है जो 3×4 के 2D एर्रे की ओर इशारा करता है। आप इसी प्रकार पॉइंटर अरिथमेटिक का उपयोग करके 3D एर्रे के तत्वों तक पहुँच सकते हैं।

एर्रे और कॉन्स्टेंट पॉइंटर्स (Arrays and Constant Pointers)

C++ में, जब आप पॉइंटर्स का उपयोग करते हैं, तो कई बार आपको यह सुनिश्चित करना पड़ता है कि पॉइंटर या तो एक निश्चित मेमोरी लोकेशन की ओर इशारा करता रहे या फिर वह मेमोरी में संग्रहीत मानों को बदलने से रोके। इस प्रकार की सुरक्षा को प्राप्त करने के लिए, आप “कॉन्स्टेंट पॉइंटर्स” (constant pointers) और “कॉन्स्टेंट डेटा” (constant data) का उपयोग कर सकते हैं। एर्रे के साथ काम करते समय, यह अवधारणा विशेष रूप से महत्वपूर्ण हो जाती है, क्योंकि इससे आप अनजाने में डेटा को संशोधित करने या पॉइंटर्स को गलत स्थानों पर इंगित करने से बच सकते हैं।

कॉन्स्टेंट पॉइंटर क्या है? (What is a Constant Pointer?)

एक कॉन्स्टेंट पॉइंटर वह पॉइंटर होता है जिसका एड्रेस (जिस लोकेशन की ओर वह इशारा करता है) नहीं बदला जा सकता है। एक बार जब कॉन्स्टेंट पॉइंटर को किसी विशेष मेमोरी लोकेशन की ओर इशारा कर दिया जाता है, तो आप उस पॉइंटर को किसी अन्य लोकेशन की ओर नहीं बदल सकते। हालाँकि, आप उस लोकेशन के डेटा को बदल सकते हैं, यदि डेटा कॉन्स्टेंट नहीं है।

उदाहरण:

int arr[5] = {10, 20, 30, 40, 50};
int *const p = arr;  // p एक कॉन्स्टेंट पॉइंटर है

*p = 15;       // मान को बदला जा सकता है
// p = &arr[1]; // यह अस्वीकार्य है, क्योंकि p एक कॉन्स्टेंट पॉइंटर है

इस उदाहरण में, p एक कॉन्स्टेंट पॉइंटर है जो arr के पहले एलिमेंट की ओर इशारा कर रहा है। आप *p के माध्यम से उस स्थान के मान को बदल सकते हैं, लेकिन आप p को किसी अन्य मेमोरी लोकेशन की ओर इशारा नहीं कर सकते।

कॉन्स्टेंट डेटा के साथ पॉइंटर (Pointer to Constant Data)

कभी-कभी, आपको यह सुनिश्चित करना होता है कि पॉइंटर जिस डेटा की ओर इशारा कर रहा है, उसे बदला न जाए। इसके लिए, आप कॉन्स्टेंट डेटा का उपयोग कर सकते हैं। इसका मतलब है कि आप पॉइंटर के माध्यम से उस स्थान के डेटा को नहीं बदल सकते, लेकिन आप पॉइंटर को किसी अन्य लोकेशन की ओर इशारा कर सकते हैं।

उदाहरण:

int arr[5] = {10, 20, 30, 40, 50};
const int *p = arr;  // p एक पॉइंटर है जो कॉन्स्टेंट डेटा की ओर इशारा करता है

// *p = 15;  // यह अस्वीकार्य है, क्योंकि p एक कॉन्स्टेंट डेटा की ओर इशारा कर रहा है
p = &arr[1]; // यह स्वीकार्य है, क्योंकि p खुद कॉन्स्टेंट नहीं है

इस उदाहरण में, p एक ऐसा पॉइंटर है जो कॉन्स्टेंट डेटा की ओर इशारा कर रहा है। आप p को किसी अन्य स्थान की ओर इशारा कर सकते हैं, लेकिन आप *p के माध्यम से डेटा को नहीं बदल सकते।

कॉन्स्टेंट डेटा और कॉन्स्टेंट पॉइंटर (Constant Data and Constant Pointer)

यह स्थिति तब उत्पन्न होती है जब पॉइंटर और डेटा दोनों ही कॉन्स्टेंट होते हैं। इस स्थिति में, आप न तो पॉइंटर के द्वारा इंगित डेटा को बदल सकते हैं और न ही पॉइंटर को किसी अन्य स्थान की ओर इशारा कर सकते हैं।

उदाहरण:

int arr[5] = {10, 20, 30, 40, 50};
const int *const p = arr;  // p एक कॉन्स्टेंट पॉइंटर है जो कॉन्स्टेंट डेटा की ओर इशारा कर रहा है

// *p = 15;  // अस्वीकार्य
// p = &arr[1];  // अस्वीकार्य

इस उदाहरण में, p एक कॉन्स्टेंट पॉइंटर है जो कॉन्स्टेंट डेटा की ओर इशारा कर रहा है। आप न तो डेटा को बदल सकते हैं और न ही पॉइंटर को किसी अन्य स्थान की ओर इशारा कर सकते हैं।

एर्रे के साथ कॉन्स्टेंट पॉइंटर्स का उपयोग (Using Constant Pointers with Arrays)

जब आप एर्रे के साथ कॉन्स्टेंट पॉइंटर्स का उपयोग करते हैं, तो यह सुनिश्चित करता है कि एर्रे के तत्वों के साथ कोई अनपेक्षित परिवर्तन नहीं होगा। यह विशेष रूप से तब उपयोगी होता है जब आप बड़ी डेटा संरचनाओं के साथ काम कर रहे हों और उन्हें सुरक्षित रखना चाहते हों।

उदाहरण:

int arr[5] = {10, 20, 30, 40, 50};
int *const p = arr;  // कॉन्स्टेंट पॉइंटर

for (int i = 0; i < 5; i++) {
    cout << *(p + i) << " ";  // एर्रे के तत्वों को प्रदर्शित करना
}

cout << endl;

इस उदाहरण में, p एक कॉन्स्टेंट पॉइंटर है जो arr की ओर इशारा कर रहा है। यह सुनिश्चित करता है कि आप गलती से पॉइंटर को किसी अन्य स्थान की ओर इशारा नहीं कर सकते, जिससे एर्रे की सुरक्षा बनी रहती है।

एर्रे के साथ पॉइंटर का उपयोग करने के फायदे (Advantages of Using Pointers with Arrays)

C++ में पॉइंटर्स का उपयोग एर्रे के साथ मिलाकर करने से कई महत्वपूर्ण फायदे प्राप्त होते हैं। ये फायदे प्रोग्रामिंग को अधिक कुशल, लचीला, और मेमोरी प्रबंधन के संदर्भ में प्रभावी बनाते हैं। आइए देखें कि एर्रे के साथ पॉइंटर्स का उपयोग करने से क्या-क्या लाभ होते हैं:

1. मेमोरी को सीधे एक्सेस और प्रबंधन करना (Direct Memory Access and Management)

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

उदाहरण:

int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;

for(int i = 0; i < 5; i++) {
    cout << "Element " << i << ": " << *(p + i) << endl;
}

इस उदाहरण में, पॉइंटर p का उपयोग करके मेमोरी में सीधे एर्रे के तत्वों तक पहुँचा जा रहा है, जिससे डेटा एक्सेस और प्रबंधन अधिक कुशल हो जाता है।

2. फंक्शन को एर्रे पास करना (Passing Arrays to Functions)

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

उदाहरण:

void printArray(int *p, int size) {
    for(int i = 0; i < size; i++) {
        cout << *(p + i) << " ";
    }
    cout << endl;
}

int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    printArray(arr, 5);
    return 0;
}

इस उदाहरण में, एर्रे को पॉइंटर के रूप में पास किया जा रहा है, जिससे मेमोरी की बचत होती है और प्रदर्शन में सुधार होता है।

3. पॉइंटर अरिथमेटिक (Pointer Arithmetic)

पॉइंटर अरिथमेटिक का उपयोग करके, आप एर्रे के किसी भी तत्व तक आसानी से पहुँच सकते हैं। यह आपको एर्रे के साथ अधिक लचीले ढंग से काम करने की अनुमति देता है, विशेष रूप से जब आपको डायनेमिक रूप से एलोकेटेड एर्रे या मल्टीडायमेंशनल एर्रे के साथ काम करना होता है।

उदाहरण:

int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;

cout << "Second element: " << *(p + 1) << endl;
cout << "Fourth element: " << *(p + 3) << endl;

इस उदाहरण में, पॉइंटर अरिथमेटिक का उपयोग करके एर्रे के विभिन्न तत्वों तक आसानी से पहुँचा जा रहा है।

4. डायनेमिक मेमोरी एलोकेशन (Dynamic Memory Allocation)

पॉइंटर्स का उपयोग डायनेमिक मेमोरी एलोकेशन के लिए किया जा सकता है, जो एर्रे के आकार को रनटाइम पर तय करने की अनुमति देता है। इससे प्रोग्राम अधिक लचीला बनता है और मेमोरी का कुशल उपयोग सुनिश्चित होता है।

उदाहरण:

int size;
cout << "Enter the size of the array: ";
cin >> size;

int *arr = new int[size];  // डायनेमिकली एर्रे का निर्माण

for(int i = 0; i < size; i++) {
    arr[i] = i * 10;
}

for(int i = 0; i < size; i++) {
    cout << arr[i] << " ";
}

delete[] arr;  // मेमोरी को मुक्त करना

इस उदाहरण में, पॉइंटर का उपयोग करके एर्रे के लिए डायनेमिक मेमोरी एलोकेट की गई है, जिससे एर्रे का आकार रनटाइम पर निर्धारित किया जा सकता है।

5. अधिक कुशल डेटा संरचनाएँ (More Efficient Data Structures)

पॉइंटर्स का उपयोग लिंक्ड लिस्ट, स्टैक, क्यू, और अन्य जटिल डेटा संरचनाओं के निर्माण के लिए किया जा सकता है, जो एर्रे के साथ काम करने में बेहद उपयोगी होते हैं। यह डेटा संरचनाएँ आपको डायनेमिक मेमोरी प्रबंधन और कुशल डेटा हेरफेर की क्षमता प्रदान करती हैं।

उदाहरण:

struct Node {
    int data;
    Node *next;
};

Node *head = nullptr;

void insert(int value) {
    Node *newNode = new Node();
    newNode->data = value;
    newNode->next = head;
    head = newNode;
}

इस उदाहरण में, लिंक्ड लिस्ट बनाने के लिए पॉइंटर्स का उपयोग किया गया है, जिससे डेटा संरचना अधिक कुशल बनती है।

सामान्य गलतियाँ और उनके समाधान (Common Mistakes and Solutions)

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

1. अनइनिशियलाइज़्ड पॉइंटर्स (Uninitialized Pointers)

गलती:

अनइनिशियलाइज़्ड पॉइंटर वह होता है जिसे किसी मेमोरी लोकेशन की ओर इशारा करने के लिए प्रारंभ नहीं किया गया होता। यदि आप ऐसे पॉइंटर का उपयोग करते हैं, तो यह अप्रत्याशित परिणाम दे सकता है या प्रोग्राम क्रैश हो सकता है।

उदाहरण:

int *p;  // p अनइनिशियलाइज़्ड पॉइंटर है
*p = 10; // अनिश्चितता का कारण बन सकता है

समाधान:

किसी भी पॉइंटर का उपयोग करने से पहले उसे nullptr या किसी वैध मेमोरी एड्रेस से इनिशियलाइज़ करना चाहिए।

int *p = nullptr;  // प्वाइंटर को nullptr से इनिशियलाइज़ करना

2. डेंगलिंग पॉइंटर्स (Dangling Pointers)

गलती:

डेंगलिंग पॉइंटर वह पॉइंटर होता है जो ऐसी मेमोरी की ओर इशारा करता है जिसे पहले ही डिलीट किया जा चुका है। इसका उपयोग करने से प्रोग्राम में गड़बड़ी हो सकती है।

उदाहरण:

int *p = new int(10);
delete p;  // p अब एक डेंगलिंग पॉइंटर है
cout << *p; // अप्रत्याशित परिणाम

समाधान:

डिलीट किए गए पॉइंटर को तुरंत nullptr से इनिशियलाइज़ करें ताकि वह डेंगलिंग न हो।

int *p = new int(10);
delete p;
p = nullptr;  // डेंगलिंग पॉइंटर को रोकने के लिए

3. पॉइंटर अरिथमेटिक में गलतियाँ (Mistakes in Pointer Arithmetic)

गलती:

पॉइंटर अरिथमेटिक का गलत उपयोग मेमोरी में गलत स्थानों तक पहुँच सकता है, जिससे डेटा भ्रष्टाचार या प्रोग्राम क्रैश हो सकता है।

उदाहरण:

int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;
cout << *(p + 5);  // यह एर्रे के बाहर पहुँचने की कोशिश कर रहा है

समाधान:

हमेशा पॉइंटर अरिथमेटिक का उपयोग करते समय यह सुनिश्चित करें कि आप एर्रे की सीमा के भीतर ही रहें।

if (p + 4 < arr + 5) {  // सीमा जांच
    cout << *(p + 4);
}

4. डायनेमिक मेमोरी लीक (Dynamic Memory Leaks)

गलती:

डायनेमिक मेमोरी एलोकेशन के बाद मेमोरी को डिलीट न करना, जिससे मेमोरी लीक हो सकती है और सिस्टम की मेमोरी खत्म हो सकती है।

उदाहरण:

int *p = new int[10];
// delete[] p; // अगर डिलीट करना भूल जाते हैं, तो मेमोरी लीक होगी

समाधान:

डायनेमिकली एलोकेटेड मेमोरी को हमेशा delete या delete[] का उपयोग करके फ्री करें।

int *p = new int[10];
delete[] p;  // मेमोरी लीक से बचने के लिए

5. रिटर्निंग एड्रेस ऑफ लोकल वेरिएबल (Returning Address of Local Variable)

गलती:

किसी फंक्शन से लोकल वेरिएबल का एड्रेस रिटर्न करना एक सामान्य गलती है, क्योंकि फंक्शन समाप्त होने के बाद यह मेमोरी डिकेलोकट हो जाती है, जिससे पॉइंटर डेंगलिंग पॉइंटर बन जाता है।

उदाहरण:

int* func() {
    int x = 10;
    return &x;  // लोकल वेरिएबल का एड्रेस रिटर्न करना
}

समाधान:

इस समस्या से बचने के लिए डायनेमिक मेमोरी एलोकेशन का उपयोग करें या वेरिएबल को स्टैटिक डिक्लेयर करें।

int* func() {
    int *p = new int(10);
    return p;  // सुरक्षित, लेकिन याद रखें कि कॉलिंग फंक्शन को delete करना होगा
}

6. एर्रे की सीमा के बाहर पहुँचने की कोशिश (Out of Bounds Access in Arrays)

गलती:

एर्रे की सीमा के बाहर पहुँचने की कोशिश करना एक सामान्य गलती है, जो डेटा भ्रष्टाचार या प्रोग्राम क्रैश का कारण बन सकती है।

उदाहरण:

int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;
cout << *(p + 10);  // एर्रे की सीमा के बाहर एक्सेस करना

समाधान:

हमेशा यह सुनिश्चित करें कि आप एर्रे के भीतर ही रहते हैं। एर्रे की सीमा की जाँच करें।

if (p + 4 < arr + 5) {  // सीमा जांच
    cout << *(p + 4);
}


Table of Contents

Index