简体   繁体   English

为结构指针成员的地址赋值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM