views:

66

answers:

2

I have been trying to create a pointer variable in the called function and somehow pass the value pointed by it to the main function. I wrote a few sample programs but it i still seem to be missing something out. and the challenge was to achieve this using pointers to pointers to pointers. Here is the code that I wrote and tested. I think am missing something obvious, can you guys point it. Thanks.

        int one(int ***ptr)
        {
            static int *p,**pp,b=10;
            p=&b;
            pp=&p;
            ptr=&pp;
            printf("b:%d\tp:%d\tpp:%d\n",b,*p,**pp);
            printf("Sub Ptr:%d\n",***ptr);
            printf("Address of ***ptr:%d\n",&ptr);
            return 32;
        }
        int main(int argc, char *argv[])
        {
              static int ***ptr;
              int a=200,*b,**c;
              b=&a;
              c=&b;
              ptr=&c;
              printf("Main Ptr:%d\n",&ptr);
              a=one(ptr);
              printf("Main Ptr:%d\n",&ptr);
              printf("Main Ptr:%d\n",***ptr);
              system("PAUSE");
              return 0;
        }

I get an output of 32 which is the return value of the function. Is it possible to get the value of 10 which is pointed in the called function.

I also tried global declaration but din work either. I would like to maintain the local declaration and see if its possible...

+1  A: 

You're setting ptr to the address-of-the-address-of-the-address-of a local variable (b), which goes out of scope at the end of the function. This is undefined behaviour. You either need to assign to ***ptr, or malloc something on the heap.

Also, you're passing ptr by value to the function. So any local modifications to it won't be reflected in main. You need to pass by pointer, i.e. you'll need an int **** as an argument.

I really hope this is nothing more than a learning exercise, because any more than two levels of pointers usually indicates that the design really needs to be re-evaluated!

Oli Charlesworth
I did this mod in the called function "int b=malloc(sizeof(int)); b=10;"but the result is still the same....is this what you meant or did I get you wrong?
Gan
No, I meant something like `p = malloc(sizeof(int)); pp = ptr = *p = 10;`.
Oli Charlesworth
I did the change by taking some memory from the heap, but still the same result. ***ptr points to 10 in the called function but when the control return to the main function it points to 32. I have no answer y this is happening. It worked in simple pointer examples i tried.
Gan
See updated answer.
Oli Charlesworth
Thanks Oli for the help
Gan
+4  A: 

I think you misunderstood about pointers. The problem of your code is that you didn't realize that pointer is also "pass by value", the pointer in the function is another variable on the stack, instead of the one you declare in the main function.

I would use a more simple example, but the idea is the same.

void changePointerValue (int * ptr) 
{
    int newValue = 10;
    ptr = &newValue;
}

int main () 
{
    int x = 20;
    int * ptr = &x;
    changePointerValue (ptr);
    printf ("After Change: %d\n", *ptr);
}

What value do you think it will output in main function? Is that be 10?

But no, in fact, it will output 20.

Why? Let's look what our code does. In the line of chagePointerValue(ptr), the computer copy the value of ptr in the main function to a new varaible on stack, let's call it ptr' and pass it to the changePointerValue function.

So in fact the ptr in the changePointerValue function is ptr', not the one you declare in the main function. The second line of changePointerValue, you assigned a new memory address to ptr', and after that, ptr' is discarded because the function is returned. The ptr in the main function remains the same value, which is the memory address pointed to x.

If you want the output to be 10, you need deference ptr in the changePointerValue, and the assignement will means 'Change the value where the ptr is pointed at'.

void changePointerValue (int * ptr) 
{
    int newValue = 10;
    *ptr = newValue;   // Now you are change the content of the memroy cell where ptr is pointed at.
}

int main () 
{
    int x = 20;
    int * ptr = &a;
    printf ("Before Change:%d", x); // 20
    printf ("Before Change:%d", *ptr); // 20
    changePointerValue (ptr);
    printf ("After Change: %d\n", *ptr); // 10
    printf ("After Change: %d\n", x); //10
}

Edit:

So, if you want it print 10 in the main function, the correct way to do this is deference ptr in the function. But this will also change the value of variable a in the main function.

    int one(int ***ptr)
    {
        ***ptr=10; // Dereference ptr to where it points to. (Varaible a in the main function)
        return 32;
    }
    int main(int argc, char *argv[])
    {
          static int ***ptr;
          int a=200,*b,**c;
          int result;
          b=&a;
          c=&b;
          ptr=&c;
          printf("Main Ptr:%d\n",&ptr); // The memory address of variable ptr.
          result=one(ptr);
          printf("Main Ptr:%d\n",&ptr); // the memory address of variable ptr.
          printf("Main Ptr:%d\n",***ptr); // 10
          printf("Main a:%d\n", a); // 10
          printf("Main result:%d\n", result); //32
          system("PAUSE");
          return 0;
    }
Brian Hsu
typo: it has to be "int *ptr = )
zerm
Thanks for the pointer, I missed 2 things one was the dereference and the heap.
Gan
@zerm: Corrected that, thanks.
Brian Hsu