I have a question that is raised from this discussion: C - modify the address of a pointer passed to a function
Let's say I have the following code:
#include <stdio.h>
foo(char **ptr){
*ptr ;
}
int main()
{
char *ptr = malloc(64);
char arr[] = "Hello World!";
memcpy(ptr, arr, sizeof(arr));
foo(&ptr);
foo(&ptr);
printf("%s",ptr);
return 0;
}
I was wondering what the output of this program would be and I thought that it should be llo World!.
After some investigation I found the question linked above and realized that, in C, parameters to functions are always passed by value. So far there was no problem. When it comes to change *ptr ; expression to -> *ptr = *ptr 1; output becomes: llo World!.
At this point, I can say that I am a little confused. In order to change pointer address, we need a double pointer. That is fine, but why do post increment operations differ? Is it because of the operator precedence?
Here I tried the example in an online C compiler.
CodePudding user response:
The postfix increment operator has higher precedence than the dereference operator *. So this:
*ptr ;
Parses as:
*(ptr );
So it changes the parameter value itself, not what it points to. You instead want:
(*ptr) ;
CodePudding user response:
Postfix operators have higher priority than unary operators. So this expression
*ptr
is equivalent to
*( ptr )
The value of the sub-expression ptr is the value of the pointer before its incrementing.
So actually you are incrementing the parameter ptr having the type char **. So this incrementing does not change the original pointer and does not make a sense.
Instead you could write
( *ptr )
But it will be more clear and less confusing to use the unary increment operator like
*ptr
if you want to increment the original pointer itself.
CodePudding user response:
As others have explained, is more important (has a higher priority) than *, so your function foo actually compiled as this:
foo (char **ptr) {
ptr = ptr 1; // This modifies the parameter, which is a copy of a variable, copied *specifically* for this function; hence, modifying it will have no effect outside of the function.
*ptr; // This is just an expression; it doesn't actually do anything, as the compiler would tell you if you wrote it this way.
}
If you change *ptr to (*ptr) , the function will work like this:
foo (char **ptr) {
*ptr = *ptr 1; // Sets the variable pointed to by ptr to be equal to itself plus one.
}
