Hi guys. I'm looking at a 'pointers to pointers' tutorial here.
Code:int **ipp; int i = 5, j = 6; k = 7; int *ip1 = &i, *ip2 = &j; ipp = &ip1;Code:Is (ipp = &ip1) == (**ipp = &i ) ?
Hi guys. I'm looking at a 'pointers to pointers' tutorial here.
Code:int **ipp; int i = 5, j = 6; k = 7; int *ip1 = &i, *ip2 = &j; ipp = &ip1;Code:Is (ipp = &ip1) == (**ipp = &i ) ?
Last edited by Tommo; 08-19-2007 at 01:07 PM.
Short answer to your direct question: No, but **ipp points to the value of i.
Theoretically it would be equal toBut there's no such thing as "&&" operand (for taking the address of an address).Code:ipp = &&i;
The variable ipp is a pointer that holds the address of another pointer. That second pointer holds the address of i.
If you think of memory as a set of safetyboxes in a bank-vault: Each one has a number. A pointer is essentially a safetybox that contains the number of a different safetybox. So if we give these a number:
i is safetybox 123, and in it is 5.
ip is safetybox number 333, in it is the number 123
ipp is safetybox 400, and it contains 333.
&i is the number of the safetybox containing i. Of course, if we change the value of i, we change the value 5 that is in box 123. The safetybox is still 123.
Does this make some sense to you.
--
Mats
This does indeed make sense, yes. Thank you very much.
So I can only declare a pointer to a pointer if such a pointer already exists - I cannot just let it equal some variable.
i.e i cant just do this:
has to be:Code:int i = 5, **pp; pp = &i;
Also, why isn't it 'int **pp = &p' ? I would've thought this following on from 'int *p = &i'Code:int i=5, **pp; int *p = &i; pp = &p;
I honestly do understand the analogy of the safetyboxes, but the specifics are still tripping me up.
Please correct me if I'm wrong but you cannot do this:
It should be this:Code:void function( int **pp ); main() { int i; function( &i ); }
Is this correct?Code:void function( int **pp ); main() { int i; int *p = &i; function( &p ); }
Last edited by Tommo; 08-19-2007 at 01:10 PM.
OK, I tried to write a little test program.
Output:Code:#include <stdio.h> void myim( int ** ); int main(void) { int i, *p; i = 5; p = &i; printf("i is %d, p is %d\n",i, *p); myim( &p ); printf("i is %d, p is %d\n", i, *p); return 0; } void myim( int **pp ) { *pp += 1; }
i is 5, p is 5
i is 5, p is -1077564144
I was expecting:
i is 5, p is 5
i is 6, p is 6
What went wrong?
this does pointer arithmetics. it changes where the pointer pointed to by pp points to -> effectively changes where p in main points to and that is not i anymore. it's the int that follows i in memory.Code:void myim( int **pp ) { *pp += 1; }
Kurt
If you want to increment what p points to, the function should look like
Code:void myim(int *p) { *p += 1; // or (*p)++; or ++*p; }
OK, then why are chars an exception to the rule:
prints 's is "this is just annoying"'.Code:#include <stdio.h> void get_string(char **s) { *s = "this is just annoying"; } int main(void) { char *s; get_string(&s); printf("s is \"%s\"\n", s); return 0; }
Now:
Compilation error. Now I know this is because p isn't pointing to anything, but with the same code for a char type, this rule doesn't seem to apply.Code:#include <stdio.h> void myim( int **pp ) { *pp = 7; } int main(void) { int *p; myim( &p ); printf("p is %d\n", *p); return 0; }
@robatino: i would have to pass '&i' in that case. The whole point to this is to use pointers to pointers.
@ZuK: I thought that was the case, thanks for clarifying. Out of curiosity, is there any way to change p and i? Do i have to change i first in order for p to change? In that case, what I was attempting was impossible?
Thanks for your help guys.
In fact, this is due to how string are represented. Look at this little exampleOK, then why are chars an exception to the rule:
Code:#include <stdio.h> void get_string(char **s) { *s = "this is just annoying"; } int main(void) { char *s; get_string(&s); printf("s is \"%s\"\n", s); return 0; }
Code:#include <stdio.h> char *string = "this is just annoying"; void get_string(char **s) { *s = string; // *(char **) = (char *) } int main(void) { char *s; get_string(&s); printf("s is \"%s\"\n", s); return 0; }
And for your other example, you shouldn't get an error, you should only get a warning (in the case warning aren't shown as errors heh).In fact, this is because int * differs in level of indirection from int, not because p isn't pointing to anything. Because you could write something like thisNow I know this is because p isn't pointing to anything, but with the same code for a char type, this rule doesn't seem to apply.and get garbage value at the output (if the program execute correctly, which might not happen, you would get the value of a int starting at adress 7) but you shouldn't get a compilation error.Code:#include <stdio.h> void myim( int **pp ) { *pp = (int *) 7; } int main(void) { int *p; myim( &p ); printf("p is %d\n", *p); return 0; }
Last edited by foxman; 08-19-2007 at 03:49 PM.
It might clarify things a bit if you wrote
since you're printing *p, not p. On the other hand, myim(&p) is changing the value of p, not *p.Code:printf("*p is %d\n", *p);
I apologize about bringing up an older thread; but I would like to add to it, rather then create a new thread.
I understand the "theory" behind pointers to pointers. However, I am having a hard time with the application of this topic. Besides using a function to return the pointer value, where else might I use pointers to pointers?
Thanks,
KiaiViper
;-)Code:int main (int argc, char ** argv) ?
QuantumPete
"No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
"Have you tried turning it off and on again?" - The IT Crowd
That would definitely be the most common scenario. Walking through pointer arrays is another--Code:int *arr[20]; int **pp; int i; pp = arr; for(i = 0; i < 20; i++) { if (**pp = 7) { // is the pointer at this place in array pointing to 7? printf("Found a seven\n"); } pp++; }
Mats
Dynamically allocated 2d arrays: i.e.
Code:#include <stdio.h> #define WIDTH 20 #define HEIGHT 20 int main(int argc, char** argv) { int** arr; int i, k, z=0; arr = malloc(HEIGHT*sizeof(int*)); for (i=0;i<HEIGHT;i++) { arr[i] = malloc(WIDTH*sizeof(int)); for (k=0;k<WIDTH;k++) { arr[i][k] = z++; } } return 0; }
Thanks for the responses. That was the clarification that I needed.
--KiaiViper