Thread: Pointer to a Pointer

  1. #1
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584

    Pointer to a Pointer

    I was just reading about the tree type in C and I saw that each node was a pointer to a pointer. What exactly is the point of making a pointer to a pointer? Thanks.
    1978 Silver Anniversary Corvette

  2. #2
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584
    > Can you paste what you saw?
    I can't quite put my finger on the code. I forget where I found that code. I'll continue to look.

    I guess my question is, why you need to have that level of indirection. A pointer to a pointer? How is that of help? I don't understand that. Thanks.
    1978 Silver Anniversary Corvette

  3. #3
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    A situation where you might need a pointer to a pointer is when you want to pass an address into a function and have that function modify what the pointer points to.

    Code:
    void foo(int** ptr)
    {
    	*ptr = malloc(sizeof(int));
    	**ptr=10;
    }
    
    int main()
    {
    
    	int* ptr;
    	foo(&ptr);
    	printf("%d",*ptr);
    	free(ptr);
    	return 0;
    }
    You could simplify this by returning the pointer from the function and then you would just pass the pointer to the function (and not it's address).
    zen

  4. #4
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584
    I understand about bringing an address into a function, but why would you want to do that? What good comes out of bringing an address of a pointer? Can't you just bring in a pointer and then it works on that address? Thanks.
    1978 Silver Anniversary Corvette

  5. #5
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    If your function is going to point your pointer at a specific location then you will need to pass in the address of a pointer.

    If you wanted a function to modify the contents of an int then you would pass the address of this int into a function, therefore if you want a function to modify the contents of a pointer (the address it points to) then you'll have to pass it's address. If you just pass a pointer any changes you make to the address that the pointer is pointing to will be local to the function.
    zen

  6. #6
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Here's a practical example of why you might need to use a pointer to a pointer.

    Consider a function which inserts a node at the beginning of a linked list.
    Code:
    // list is the pointer to the first element in the list
    // addMe points to the node you're adding
    void addLStart (node * list, node * addMe)
    {
     // First, the node your adding should point at 
     //  the first node in the list...
     addMe -> next = list;
     // then change list to it points addMe, which 
     //  shall be the new first node
     list = addme;
     return;
    }
    WRONG! You've fixed the node after addMe, but the pointer to the list is still pointing at the same element, you just changed the value of the function's copy of list.
    Code:
    void addLStart (node ** list, node * addMe)
    {
     addMe -> next = list;
     *list = addme;
     return;
    }
    Ahh, much better. Now... I don't really know too much about trees, but here's what I suspect the deal is there. Here's what the node structure mught look like for a tree..
    Code:
    typedef struct
    {
     int value;
     tNode ** next;
    } tNode
    Then it's best to think of tNode not as a pointer to a pointer (actually, maybe you should think of it as one..) but rather as an array of pointers. That is to say, in a tree, each node may have 1, 2, 3, or however so many children. Here is an example function utilizing this...
    Code:
    void dispChildren (tNode * node)
    {
     tNode ** n;
     int i;
     printf ("The current node is %d\n\n", node -> value);
     /* Pick a version, any version...
     // This is the version that actually makes sense...
     for (n = node -> next, i = 0;  &n[i] != NULL; i++)
     {
      printf ("Child #%d: %d\n", i, n[i] -> value);
     }
    
     // This is the version of unsurpassed leet, which 
     //  relishes in the beauty and awe of pointers!
     for (n = node -> next, i = 0; n != NULL; n++, i++)
     {
      printf ("Child #%d: %d\n", i, (*n) -> value);
     }
        ... Choose your fate wisely young one. */
     return;
    }
    I hope the code is understandable. Notice that I chose to represent the children like a string... a list of elements, ended by a null character. There are other ways of handling how many children there are, it all depends on how you choose to implement the tree.

    EDIT: I am addicted to using comments in code which are too long, and mess up the browser window
    Last edited by QuestionC; 09-23-2001 at 09:12 PM.

  7. #7
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    You know what? I'm stupid. I write that long big post, walk away, come back, and realise that I didn't give a reason for using a tNode ** at all. Why use a table of tNodes when you could just use an array of tNodes? I can think of a structure where that'd be neccisary... but it's not a tree.

    Of course, there are upsides to using an array of pointers to structures instead of an array of structures, the biggest one being that if your structures are of great number or size, then an array would have to put them in a continuous memory block, which has it's downsides, but that doesn't mean you can't still store the children as an array.

  8. #8
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584
    So, you're saying if I do this:
    Code:
    char *chngstr(char *string)
    {
        string[0] = 'A';
        return string;
    }
    
    int main()
    {
        char new_string[] = "Garfield";
        printf("%s\n", new_string);
        chngstr(new_string);
        printf("%s", new_string);
    
        return (0);
    }
    Will this print out:
    Garfield
    Aarfield

    Or will this print out:
    Garfield
    Garfield

    So, if the function only has the changes local, then it should print out the second selection, right? If this is right, then I understand what you are saying. Thanks.
    1978 Silver Anniversary Corvette

  9. #9
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    So, if the function only has the changes local, then it should print out the second selection, right?
    No, firstly you're not pointing the string pointer anywhere else, you are only changing a value in a memory location that the original char pointer points to, and even if you were pointing the pointer elsewhere then the value would be retained (as long as the memory location it was set to was not local to the function and on the stack) as you are returning the pointer from your function.

    Therefore there is no need to return the pointer. Your function modifies the contents of the string pointed to by the char pointer passed into the function.

    If you try this, it will show that the string points elsewhere in the function, but that this is only local to the function -

    Code:
    #include <stdio.h>
    
    
    char name[]="zen";
    
    void chngstr(char *string)
    {
        string = name;
    	printf("In function string = %s\n",string);
        
    }
    
    int main()
    {
        char new_string[] = "Garfield";
        printf("Before Function string = %s\n", new_string);
        chngstr(new_string);
        printf("After function has returned string = %s\n", new_string);
    
        return 0;
    }

    Two of the possible methods of making this change permanent are firstly returning the pointer from the function -

    Code:
    #include <stdio.h>
    
    char* name="zen"; 
    
    char* chngstr(char *string)
    {
        string = name;
    	printf("In function string = %s\n",string);
    	return string;
        
    }
    
    int main()
    {
        char* new_string = "Garfield";
        printf("Before Function string = %s\n", new_string);
        new_string =chngstr(new_string);
        printf("After function has returned string = %s\n", new_string);
    
        return 0;
    }
    Note - you shouldn't try modify the contents of these strings when using char pointers instead of arrays.

    A second method would be using a pointer to a pointer and not returning a pointer to string -

    Code:
    #include <stdio.h>
    
    char* name="zen";
    
    void chngstr(char **string)
    {
        *string = name;
    	printf("In function string = %s\n",*string);
    	    
    }
    
    int main()
    {
        char* new_string = "Garfield";
        printf("Before Function string = %s\n", new_string);
        chngstr(&new_string);
        printf("After function has returned string = %s\n", new_string);
    
        return 0;
    }
    zen

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  2. Quick Pointer Question
    By gwarf420 in forum C Programming
    Replies: 15
    Last Post: 06-01-2008, 03:47 PM
  3. Parameter passing with pointer to pointer
    By notsure in forum C++ Programming
    Replies: 15
    Last Post: 08-12-2006, 07:12 AM
  4. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM