[英]Assigning value to the address of member of a struct pointer
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
.我要做的就是移动到
struct abc *obj
指向的区域并更改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.我创建了指向包含
&obj+sizeof(uint8_t)
地址的指针的指针,这个sizeof(uint8_t)
将使我们通过obj->i
拥有的区域,该区域也是 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但是当我打印
obj->j
仍然是0
时,代码并没有真正起作用 我怎样才能进入 memory 区域并更改 j 的值,所以obj->j
将打印 5
My system processor is x86-64我的系统处理器是 x86-64
First, please add the definition of struct abc
.首先,请添加
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.这表示将
obj
的地址作为struct abc
指针,然后将sizeof(uint8_t)
即 1 添加到其中,但由于表达式的类型是struct abc *
,因此它是一个sizeof(struct abc)
字节移动,这可能不是你想要的。 Also, that should be uint8_t *j
.此外,这应该是
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: offsetof()
是一个更好的选择,像这样使用:
uint8_t *j = (char *) &obj + offsetof(obj, j);
I think you just want to change the value of j by accessing the memory location.我认为您只想通过访问 memory 位置来更改 j 的值。 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.但是,如果您想使用跳过字节来更改值,那么 Ken YN 的答案。
You need to access the address of obj without & because *obj is already a pointer:您需要在没有 & 的情况下访问 obj 的地址,因为 *obj 已经是一个指针:
#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: 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:我添加了一个 uint16_t 来进一步说明,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注意:我们得到 0x0500 因为小端序:cpu 内部字节是 0x00 后跟 0x05,但变量
a
将从右到左读取字节值
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.