Search code examples
c++pointersdouble-pointer

How a double pointer fetch the value from a single poiner


An array is right now pointed by a single pointer. And a double pointer is pointing to the single pointer. I am trying to fetch the value of the array using this double pointer. As far I have only fetched the first index value of the array by the double pointer. I know that if I dereference (*ptr2) a double pointer then it will give the address where the first pointer is pointed (ptr1) which means the first index address of the array(&array[0]).

#include <iostream>
using namespace std;

int main(){
    int array[5]{15,25,35,45,55};
    int* ptr1;
    int** ptr2;

    ptr1 = &array[0];
    ptr2 = &ptr1;

In the following for loop, I have tried to print the value of array using pointer ptr1.

    for(int i =0; i<5; i++){
        cout<<"the value: "<<*(ptr1+i)<<" lives at "<<ptr1+i<<" address\n";
    }
    cout<<"\n";

In the following for loop I have tried to check *ptr2 is all-time giving me address pointed by ptr1 or not. But I have found that it only works/same for the first index then it is (*ptr2) giving me a different address

    for(int j=0; j<5; j++){
        cout<<"adress of array: "<<&array[j]<<" , ptr1: "<<(ptr1+j)<<" , val of ptr2: "<<*(ptr2+j)<<endl;
    }

    cout<<"\n";
    return 0;
}

While I have tried to fetch the value from ptr2 by using **ptr2+i using a for loop it continues only for 2 times. First-time correct value which is obvious as I am seeing the address of array[0] and *(ptr2+0) are same. Second-time garbage value and then Segmentation fault (core dumped).

One guess came in my mind that ptr1 and ptr2 both are int type but one is pointing to a variable and another is to a pointer. So maybe there is a memory allocation concept arises from the very beginning which I am skipped.

Is there any way where I can fetch the value of the array using the mentioned structure?


Solution

  • Your reasoning is close, but you did not apply it well.

    I know that if I dereference (*ptr2) a double pointer then it will give the address where the first pointer is pointed (ptr1)

    In other words, *ptr2 is a synonym for ptr1. So any place you see ptr1 (after assigning ptr2 = &ptr1) you can substitute in *ptr2. Even better, substitute in (*ptr2) to avoid interference from operators with a higher precedence than de-reference. Let's take an example:

       for(int i =0; i<5; i++){
           cout<<"the value: "<<*(ptr1+i)<<" lives at "<<ptr1+i<<" address\n";
       }
       cout<<"\n";
    

    Now do a simple find-and-replace. Replace ptr1 with (*ptr2). Don't try to adjust anything; once you've decided to do this, the process is mindless.

        for(int i =0; i<5; i++){
            cout<<"the value: "<<*((*ptr2)+i)<<" lives at "<<(*ptr2)+i<<" address\n";
        }
        cout<<"\n";
    

    This is almost what you tried in your loop, except you used *(ptr2+j) instead of (*ptr2)+i. We can ignore the change from i to j, but those parentheses are significant. You changed the order of operations, which is comparable to using 3(1+4) instead of (3×1)+4. It shouldn't be surprising that 15 does not work where 7 is needed, and similarly adding j before de-referencing does not work where the de-reference needs to be done first.

    Note: Since de-reference has a higher precedence than addition, the parentheses around *ptr2 could be dropped from this particular example. That is, *ptr2+i and *(*ptr2+i) would also work.

    Note: This question can serve as a demonstration of why it's often wise to avoid pointers-to-pointer.