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.
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
> 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
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.
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).Code:void foo(int** ptr) { *ptr = malloc(sizeof(int)); **ptr=10; } int main() { int* ptr; foo(&ptr); printf("%d",*ptr); free(ptr); return 0; }
zen
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
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
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.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:// 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; }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:void addLStart (node ** list, node * addMe) { addMe -> next = list; *list = addme; return; }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:typedef struct { int value; tNode ** next; } tNodeI 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.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; }
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.
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.
So, you're saying if I do this:
Will this print out: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); }
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
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.So, if the function only has the changes local, then it should print out the second selection, right?
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 -
Note - you shouldn't try modify the contents of these strings when using char pointers instead of arrays.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; }
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