繁体   English   中英

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

[英]Assigning value to the address of member of a struct pointer

我有这个代码

  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);

我要做的就是移动到struct abc *obj指向的区域并更改obj->j的值。 我创建了指向包含&obj+sizeof(uint8_t)地址的指针的指针,这个sizeof(uint8_t)将使我们通过obj->i拥有的区域,该区域也是 uint8_t。 但是当我打印obj->j仍然是0时,代码并没有真正起作用 我怎样才能进入 memory 区域并更改 j 的值,所以obj->j将打印 5

我的系统处理器是 x86-64

首先,请添加struct abc的定义。 我认为它看起来像:

struct abc {
    uint8_t byte_we_want_to_skip;
    uint8_t j;
};

在这一行:

uint8_t **j=(uint8_t *)(&obj+ sizeof(uint8_t));

这表示将obj的地址作为struct abc指针,然后将sizeof(uint8_t)即 1 添加到其中,但由于表达式的类型是struct abc * ,因此它是一个sizeof(struct abc)字节移动,这可能不是你想要的。 此外,这应该是uint8_t *j 所以,你应该使用什么:

uint8_t *j = (uint8_t *)((char *)&obj+ sizeof(uint8_t));

另请注意,所有这些指针摆弄都是未定义的行为,因此不能保证在任何地方都可以使用。 offsetof()是一个更好的选择,像这样使用:

uint8_t *j = (char *) &obj + offsetof(obj, j);

我认为您只想通过访问 memory 位置来更改 j 的值。 您可以通过直接访问这样的位置来做到这一点。

uint_t *j = &(obj->j);
*j = 5;

但是,如果您想使用跳过字节来更改值,那么 Ken YN 的答案。

您需要在没有 & 的情况下访问 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:

address of obj => 0x55bbc5f84260 - value in obj->j: 5
address of   j => 0x55bbc5f84261 - value at j address: 5 

或者你可以把你的结构放在堆栈上,然后你可以使用 & 来访问它的地址:

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;
}

我添加了一个 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 

注意:我们得到 0x0500 因为小端序:cpu 内部字节是 0x00 后跟 0x05,但变量a将从右到左读取字节值

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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