测试代码如下:
#include <stdio.h>
typedef struct
{
int a;
char b;
short c;
short d;
int e;
} TEST;
void main()
{
TEST x;
printf("struct addr: %d\t%d\t%d\n", &x, (char*)&x, (char*)&x.a);
printf("element addr: %d\t%d\t%d\t%d\t%d", &x.a, &x.b, &x.c, &x.d, &x.e);
}
执行结果如下:
struct addr: 6422032 6422032 6422032
element addr: 6422032 6422036 6422038 6422040 6422044
1、结构体的首地址获取
根据执行结果可以看出对结构体变量直接取地址,或者对首个元素取地址均可获取结构体所占内存的首地址,再根据需要转成char*或void*即可。
2、结构体内存对齐规则
测试代码打印的内存分布如图:
(1)结构体内存对齐是按照内存占用最高元素的整数倍进行的,测试代码中为4字节
(2)每个最高元素整数倍的内存块内,同样按照(1)的规则进行,例如6422036中b和c两个元素中,最高字节为c,2个字节,在6422036起始的4字节内也按照2字节对齐
3、如何改变结构体内部的内存对齐方式?
使用如下格式将内存对齐方式改为n字节对齐
#pragma pack(n)
struct
{
//data
} TEST;
#pragma pack()
对于测试代码,改为2字节对齐:
#include <stdio.h>
#pragma pack(2)
typedef struct
{
int a;
char b;
short c;
short d;
int e;
} TEST;
#pragma pack()
void main()
{
TEST x;
printf("struct addr: %d\t%d\t%d\n", &x, (char*)&x, (char*)&x.a);
printf("element addr: %d\t%d\t%d\t%d\t%d", &x.a, &x.b, &x.c, &x.d, &x.e);
}
执行结果如下:
struct addr: 6422034 6422034 6422034
element addr: 6422034 6422038 6422040 6422042 6422044
改为1字节对齐:
#include <stdio.h>
#pragma pack(1)
typedef struct
{
int a;
char b;
short c;
short d;
int e;
} TEST;
#pragma pack()
void main()
{
TEST x;
printf("struct addr: %d\t%d\t%d\n", &x, (char*)&x, (char*)&x.a);
printf("element addr: %d\t%d\t%d\t%d\t%d", &x.a, &x.b, &x.c, &x.d, &x.e);
}
执行结果如下
struct addr: 6422035 6422035 6422035
element addr: 6422035 6422039 6422040 6422042 6422044