前言

之前只是最简单的认为结构体中内存的分配与变量和数组在内存中的分配如出一辙,在刚才看王敬华老师“C语言程序设计教程”这本书才知道TC,BC,VC下结构体在内存中分配的区别

引言:

1
2
3
4
5
6
struct MyStruct
{
double x;
char y;
int z;
} a;

在TC与BC中, int占2字节, 在VC中 int占4字节, double与char和在TC,BC中占的字节数一样分别是8、1字节

那么,这个结构体在TC,BC与VC中占据的字节一样么?

肯定是不一样的,一个是各个成员所占内存空间的大小之和,而VC则是根据规则计算出来,并不一定等于各个成员所占内存空间的大小


TC,BC环境下的结构体变量内存分配

在TC与BC编译环境下,结构体变量所占内存空间的大小等于它所包含的每个成员所占内存空间的大小


VC环境下结构体变量内存分配

遵循两个规则

  1. 默认情况下,VC环境下各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该成员变量类型所占用的字节数的倍数
  2. 为了确保结构体变量所占内存空间的大小为结构体的字节边界数(即该结构体中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。
类型对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)
char偏移量必须为sizeof(char)即1的倍数
short偏移量必须为sizeof(short)即2的倍数
int偏移量必须为sizeof(int)即4的倍数
long偏移量必须为sizeof(long)即4的倍数
float偏移量必须为sizeof(float)即4的倍数
double偏移量必须为sizeof(double)即8的倍数

题目1

1
2
3
4
5
6
struct MyStruct
{
double x;
char y;
int z;
} a;
  1. TC与BC环境中:8 + 1 + 2 = 11字节
  2. VC环境中:8 + 1 + 3(为构成12,也就是为int整数倍而填充) + 4(最后发现是16字节,是占最大字节数double的2倍,故不用填充) = 16字节

题目2

1
2
3
4
5
6
7
8
9
struct Student_Info
{
char no[9]; //学号
char name[20]; //姓名
char sex; //性别
unsigned int age; //年龄
unsigned int classno;//班级
float grade; //成绩
};
  1. TC与BC环境中:9 + 20 + 1 + 2 + 2 + 4 = 38字节
  2. VC环境中:9 + 20(检查发现9是1的整数倍) + 1 + 2(填充2字节,构成int的4字节的整数倍) + 4 + 4 + 4(最后检查发现是所占用字节数最大int与float类型的整数倍,故不用填充) = 44字节;