#include <stdio.h>
#include <stdlib.h>
typedef struct person {
char *name;
unsigned int age;
unsigned int height;
unsigned int weight;
} person_t;
int main() {
void *p;
person_t *p1;
p = malloc(sizeof(person_t));
p1 = (person_t *)p;
p1->name = malloc(80*sizeof(char));
p1->name = "my_name";
p1->age=25; p1->height=6; p1->weight=65;
printf("\n%p -> %u == ",(p+12),*(unsigned int *)(p+12)) ;
printf("%p -> %u",&p1->height,p1->height) ;
return 0;
}
输出:
0x16c46b4 -> 6 == 0x16c46b4 -> 6
两次打印都打印相同的指针和值。有人可以帮助我更清楚地理解它吗?
执行上面的代码并理解,从两个打印中都可以得到相同的o/p,但仍然不方便清楚。
您的代码不可移植,因为它依赖于一些实现细节。
您正在使用一个系统,其中
int
似乎有 32 位,而指针有 64 位大。
您的结构中也没有填充。
最后,您在 GCC 中使用非标准扩展,将 void*
视为 char*
。
这意味着,该结构的内存布局如下所示:
+--------+------------+--------+
| offset | field | size |
+--------+------------+--------+
| 0 | char *name | 8 |
+--------+------------+--------+
| 8 | uint age | 4 |
+--------+------------+--------+
| 12 | uint height| 4 |
+--------+------------+--------+
| 16 | uint weight| 4 |
+--------+------------+--------+
这意味着,如果您获取该结构体的地址并添加 12 个字节,您将获得
height
成员的地址。
您可以通过打印 offsetof(person_t, height)
来验证这一点。
如果您这样做
&p1->height
,编译器会为您进行计算。
如果您这样做
p+12
,您可以手动进行计算并得到相同的结果。
这依赖于允许使用 void*
进行计算的 GCC 扩展。它的作用与 char*
相同,这意味着指针算术添加单个字节。