gpt4 book ai didi

c - 通过将 void 指针转换为不同的结构指针来访问其内容

转载 作者:行者123 更新时间:2023-11-30 14:47:02 25 4
gpt4 key购买 nike

在C中,假设我有一个通用指针,用于存储所有数据,在本例中,为指针内容分配了四个整数的大小。

void * gen_purpose_ptr = SOME_MEMORY_ADDRESS;
gen_purpose_ptr = malloc(4*sizeof(int));

有两个结构使用此指针来访问其内容:

struct Struct_1 {
int data1, data2;
};

struct Struct_2 {
int data3, data4;
};

现在如果我这样做

( (struct Struct_1 *)gen_purpose_ptr ) -> data1 = VALUE_A;
( (struct Struct_1 *)gen_purpose_ptr ) -> data2 = VALUE_B;
( (struct Struct_2 *)gen_purpose_ptr ) -> data3 = VALUE_C;
( (struct Struct_2 *)gen_purpose_ptr ) -> data4 = VALUE_D;

在这种情况下, VALUE_A 会吗? , VALUE_B , VALUE_C , VALUE_D是否能够正确存储而不会互相覆盖?

当转换和赋值操作完成后,编译器是否知道特定的内存只能由特定的结构成员访问?

最佳答案

让我们亲自看看!

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

void printhex(const void *pnt0, size_t s)
{
const unsigned char *pnt = pnt0;
while(s--) {
printf("%02x", *pnt++);
}
}

void printhexln(const char *pre, const void *pnt, size_t s, const char *post)
{
printf("%s", pre);
printhex(pnt, s);
printf("%s", post);
printf("\n");
}

struct Struct_1 {
unsigned int data1, data2;
};

struct Struct_2 {
unsigned int data3, data4;
};

int main()
{
// let's grab memory for 4 ints
size_t size = 4 * sizeof(int);
void * ptr = malloc(size);
assert(ptr != NULL);
// let's zero that memory
memset(ptr, 0, size);
// this will print zeros
printhexln("1: ", ptr, size, "");

( (struct Struct_1 *)ptr ) -> data1 = 0x1122;
printhexln("2: ", ptr, size, "");
( (struct Struct_1 *)ptr ) -> data2 = 0x3344;
printhexln("3: ", ptr, size, "");
( (struct Struct_2 *)ptr ) -> data3 = 0x5566;
printhexln("4: ", ptr, size, "");
( (struct Struct_2 *)ptr ) -> data4 = 0x7788;
printhexln("5: ", ptr, size, "");

free(ptr);
return 0;
}

将在 https://www.onlinegdb.com 上输出:

1: 00000000000000000000000000000000
2: 22110000000000000000000000000000
3: 22110000443300000000000000000000
4: 66550000443300000000000000000000
5: 66550000887700000000000000000000

printhex 是一个简单的函数,它以十六进制字符打印指针后面的内存。我们可以看到:

  1. 首先只有零。我们可以数一下零,然后看到 size = 16sizeof(int) = 4
  2. 然后,我们将指针转换为 struct Struct_1 并将 data1 设置为 0x1122。指针的前 2 个字节被覆盖并设置为 0x2211,因为机器是小端字节序。 ((struct Struct_1)ptr)->data1 的值现在等于 0x00001122
  3. 我们可以看到,将 4433 写入 ((struct Struct_1*)pnt)->data2 将字节 5 和 6 设置为 0x4433。机器是小端字节序,sizeof(int) = 4,我们可以看到offsetof(struct Struct_1, data2) = 4
  4. 将结构转换为 Struct_2 并写入 data3,覆盖前 2 个字节,而不关心之前的值。这是因为 offsetof(struct Struct_2, data3) = 0,因此 data3 从指针的开头开始。
  5. 嗯,当写入 Struct_2 的 data4 成员时,4433 被 8877 覆盖

关于c - 通过将 void 指针转换为不同的结构指针来访问其内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51714474/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com