簡體   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