结构体与&结构体的打印地址差异及内存分配疑问
结构体内存分配与地址打印问题解析
问题根源:错误的打印方式
你代码里的printf("1: %x ", next);是错误的,这不是在打印结构体的地址。原因是:
%x格式符要求传入整数或指针类型,但你直接传递了整个结构体变量next。在C语言中,结构体作为函数参数传递时会发生值拷贝,把结构体的所有成员按顺序压入栈中。- printf作为可变参数函数,会按照
%x的要求从栈中取第一个4字节数据(假设int是4字节),也就是结构体第一个成员x的值,而不是结构体的地址。 - 而
&next才是结构体变量的真实地址,所以两者输出自然不同。
结构体的内存分配规则
结构体的内存分配没有额外的前置字节,核心规则是:
- 连续存储:结构体成员按照声明顺序依次分配内存,内存块是连续的。
- 内存对齐:为了提升CPU访问效率,编译器会自动在成员之间或末尾填充空白字节,使得每个成员的地址都符合其数据类型的对齐要求,但不会在结构体开头加额外字节。
- 结构体变量的地址,就是其第一个成员的地址,比如
&next和&next.x的值完全相等。
以你的Point结构体为例:
- 32位系统:int占4字节,指针占4字节,总大小8字节(无填充)。
- 64位系统:int占4字节,指针占8字节,编译器会在int后面填充4字节,使得指针成员对齐到8字节地址,总大小16字节。
修正后的代码示例
#include <stdio.h> typedef struct Point { int x; struct Point* net; } Point; int main() { Point next; // 打印结构体地址(正确用法:%p对应指针类型) printf("结构体地址: %p\n", &next); // 打印第一个成员x的地址,与结构体地址一致 printf("成员x的地址: %p\n", &next.x); // 打印结构体成员的值 printf("成员x的值: %x\n", next.x); printf("成员net的值: %p\n", next.net); return 0; }
运行后你会看到,结构体地址和成员x的地址完全相同,证明结构体开头没有额外占用字节。
内容的提问来源于stack exchange,提问作者Ngoc Le
相关产品推荐
相关产品推荐

