I have this code
struct abc *obj=(struct abc *)malloc(sizeof(struct abc));
uint8_t **j=(uint8_t *)(&obj+ sizeof(uint8_t));
*j=5;
printf("%d\n",obj->j);
What I am trying to do is to just move into the area pointed to by struct abc *obj
and change the value of obj->j
. I have created pointer to pointer that contains the address of &obj+sizeof(uint8_t)
in this sizeof(uint8_t)
will get us passed the area possessed by obj->i
which is also uint8_t. but the code is not really working when I print obj->j
which is still 0
How can I move into the memory area and change the value of j so obj->j
will print 5
My system processor is x86-64
First, please add the definition of struct abc
. I presume it looks like:
struct abc {
uint8_t byte_we_want_to_skip;
uint8_t j;
};
In this line:
uint8_t **j=(uint8_t *)(&obj+ sizeof(uint8_t));
This says take the address of obj
as a struct abc
pointer, then add sizeof(uint8_t)
ie 1 to it, but since the type of the expression is struct abc *
, it is one sizeof(struct abc)
bytes that you move, which is probably not what you want. Also, that should be uint8_t *j
. So, what you should be using:
uint8_t *j = (uint8_t *)((char *)&obj+ sizeof(uint8_t));
Note also that all this pointer fiddling is undefined behaviour, so it is not guaranteed to work everywhere. offsetof()
is a better alternative, used like so:
uint8_t *j = (char *) &obj + offsetof(obj, j);
I think you just want to change the value of j by accessing the memory location. You can do so by directly accessing the location like this.
uint_t *j = &(obj->j);
*j = 5;
But if you want to change the value using skipping bytes then Ken YN's answer.
You need to access the address of obj without & because *obj is already a pointer:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
struct abc {
uint8_t byte_we_want_to_skip;
uint8_t j;
};
int main(void) {
struct abc *obj= malloc(sizeof(struct abc));
uint8_t *j = (uint8_t*)((char *)obj+ sizeof(uint8_t)); // remove the &
*j = 5;
printf("address of obj => %p - value in obj->j: %d\n",obj, obj->j);
printf("address of j => %p - value at j address: %d \n", j, *j);
return 0;
}
output:
address of obj => 0x55bbc5f84260 - value in obj->j: 5
address of j => 0x55bbc5f84261 - value at j address: 5
Or you can have your struct on the stack and then you can use & to access its address:
int main(void) {
struct abc obj;
uint8_t *j = (uint8_t*)((char *)&obj+ sizeof(uint8_t));
*j = 5;
printf("address of obj => %p - value in obj.j: %d\n", &obj, obj.j);
printf("address of j => %p - value at j address: %d \n", j, *j);
uint16_t *a = (uint16_t*)((char *)j - 1);
printf("address of a => %p - value at a address: %x \n", a, *a); // will print j * 100 in hexa
*a = 42 | 3 << 8;
printf("\naddress of obj => %p - value in obj.i: %d\n", &obj, obj.i);
printf("address of obj => %p - value in obj.j: %d\n", &(obj.j), obj.j);
printf("address of j => %p - value of j: %d \n", j, *j);
return 0;
}
I added an uint16_t to illustrate a bit more, output:
address of obj => 0x7ffecc5fa536 - value in obj.j: 5
address of j => 0x7ffecc5fa537 - value at j address: 5
address of a => 0x7ffecc5fa536 - value at a address: 500
address of obj => 0x7ffecc5fa536 - value in obj.i: 42
address of obj => 0x7ffecc5fa537 - value in obj.j: 3
address of j => 0x7ffecc5fa537 - value of j: 3
NB: We get 0x0500 because of little endianness : inside the cpu bytes are 0x00 followed by 0x05, but the variable a
will read bytes values from right to left
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.