Reputation: 427
I want to execute the following code, but through a function.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
char* string = "hello_World";
string++;
printf("%s\n", string);
// ignore memory leak for sake of quiz
return 0;
}
OUTPUT:
ello_World
Now instead of incrementing the pointer inside main
I tried to pass the reference of the pointer to a function and then increment it.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void myfunc(char** param){
param++;
}
int main(){
char* string = "hello_World";
myfunc(&string);
printf("%s\n", string);
return 0;
}
But the OUTPUT was hello_World
Can you please tell me what is happening in the code that I wrote and how can I change it for the desired result?
Upvotes: 2
Views: 793
Reputation: 12669
In myfunc()
function, the pointer param
is pointing to string
pointer. It will look something like this:
---
param |-|--
--- |
|
|
---
string |-|----
--- |
|
|
--------------------------
|h|e|l|l|o|_|W|o|r|l|d|\0|
--------------------------
When you do param++
, it will result in incrementing the pointer by the size of pointer1) on your platform because param
can point to a char
pointer. Assume that size of pointer is 8
(64
bit platform) and assume the address of string
pointer is 100
, then param++
will result in pointer param
pointing to 108
address. Note that it will not affect string
pointer in anyway. It will look something like this:
108
--- ---
param++ --> param |-|-------| |
--- ---
---
string |-|----
--- |
|
|
--------------------------
|h|e|l|l|o|_|W|o|r|l|d|\0|
--------------------------
Now, when you print the string
in main()
function, you are getting the output "hello_World".
To demonstrate this, I have added few printf()
statement in your program:
#include <stdio.h>
void myfunc(char** param){
printf ("param : %p\n", (void *)param);
printf ("*param : %p\n", (void *)*param);
param++;
printf ("param : %p\n", (void *)param);
printf ("*param : %p\n", (void *)*param);
}
int main(void){
char* string = "hello_World";
printf ("string : %p\n", (void *)string);
myfunc(&string);
printf ("string : %p\n", (void *)string);
printf("%s\n", string);
return 0;
}
Output:
string : 0x10a654f97
param : 0x7ffee55abad0
*param : 0x10a654f97
param : 0x7ffee55abad8 ======> result of incrementing param
*param : 0xcb7d025 ======> result of incrementing param
string : 0x10a654f97 ======> not affected
hello_World
To get the desired behaviour, in the myfunc()
function, you should first dereference the param
pointer to get the string
pointer and then increment it i.e. you should do (*param)++
. It will result in increment the string
pointer by size of a char
1):
---
param |-|--
--- |
|
|
---
(*param)++ --> string |-|-------
--- |
|
|
--------------------------
|h|e|l|l|o|_|W|o|r|l|d|\0|
--------------------------
Demonstration:
#include <stdio.h>
void myfunc(char** param){
printf ("param : %p\n", (void *)param);
printf ("*param : %p\n", (void *)*param);
(*param)++;
printf ("param : %p\n", (void *)param);
printf ("*param : %p\n", (void *)*param);
}
int main(){
char* string = "hello_World";
printf ("string : %p\n", (void *)string);
myfunc(&string);
printf ("string : %p\n", (void *)string);
printf("%s\n", string);
return 0;
}
Output:
string : 0x100de5f97
param : 0x7ffeeee1aad0
*param : 0x100de5f97
param : 0x7ffeeee1aad0
*param : 0x100de5f98
string : 0x100de5f98
ello_World
Upvotes: 3
Reputation: 140970
The memory could be looking like the following. The 0x1122*****
represent some address of the byte below it. Each +---+
box represents one byte with the value inside. Below are the function names with variable names. The ---->
arrows represent "points to" relation between pointer and memory. The illustration assumes a pointer has 4 bytes and data are stored in big endian, which is most probably not true on the architecture you are running, but it's just to illustrate the point.
0x11223000 0x11223300 0x11223344
+------+------+------+------+ +------+------+------+------+ +---+---+---+---+---+---+---+---+---+---+---+------+
| 0x11 | 0x22 | 0x33 | 0x00 | . . . . . . . . . | 0x11 | 0x22 | 0x33 | 0x44 | . . . . . | h | e | l | l | e | _ | W | o | r | l | d | 0x00 |
+------+------+------+------+ +--------->+------+------+------+------+ +---+---+---+---+---+---+---+---+---+---+---+------+
| ^
+---------------------------+---------+ +---------------------------+-----------+
myfunc::param main::string
When you do param++
in myfunc
you are incrementing the value of param
, not the value it points to. Pointers are increment by the size they are pointing to, so param
beeing char**
will be incremented by sizeof(char*)
. In my illustration above, a pointer has 4 bytes, so doing param++
increments param = 0x11223300
to param = 0x11223304
and it points somewhere after main::string
into some unknown memory region.
If you mean to do this:
0x11223300 0x11223344
+------+------+------+------+ +---+---+---+---+---+---+---+---+---+---+---+------+
| 0x11 | 0x22 | 0x33 | 0x45 | . . . . . | h | e | l | l | e | _ | W | o | r | l | d | 0x00 |
+------+------+------+------+ +---+---+---+---+---+---+---+---+---+---+---+------+
^
+---------------------------+---------------+
main::string
Then you have to increment the string
pointer inside main
. Because param
points to string
, you may (*param)++
- increment the value of what the param
points to, so increment the string
pointer inside main
. Because string
is a char*
, it will be incremented by sizeof(char)
- which is 1
.
Upvotes: 3
Reputation: 3524
You incremented the pointer to the pointer, you would need (*param)++;
Upvotes: 3