结构体的实际占用大小

结构体理论占用的大小 不一定等于 实际占用的大小
主要是因为字节对齐引起的问题

引用资料:字节对齐与结构体大小

  • 结构体变量的首地址能够被其最宽基本类型成员的大小所整除
  • 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节
  • 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节
  1. struct Person {
  2. char *name;
  3. int age;
  4. int height;
  5. int weight;
  6. };

上面这个结构体,sizeof(struct Person)的大小为24,但是根据字节数推算应该是20(8 + 4 + 4+ 4)
根据上面的第3条原则,结构体总大小需要补全为最宽基本类型(8位的name),所以最终长度为24。
|—— ——|
name,8字节
|——|——| age和height
|——|——| weight和4个空白字节

  1. struct student
  2. {
  3. int num;
  4. char name[5];
  5. short score;
  6. };

此时sizeof(struct student) = 12, 其数据对齐如下图:
image.png

引用资料

Anki制卡

.|如何为struct Persion申请一块内存,在使用完成后,如何释放?

.|#include
Struct Person person = malloc(sizeof(struct Person));
free(person)
*.+

.|字节对齐的基本准则是什么?

.|

  • 结构体变量的首地址能够被其最宽基本类型成员的大小所整除
  • 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节
  • 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节

.+

.|下面的结构体,实际占用的内存空间是多少?为什么?

struct Person { char *name; int age; int height; int weight; };

.|
答案:24个字节
执行sizeof(struct Person)的结果为24,但是根据字节数推算应该是20(8 + 4 + 4+ 4)
根据上面的第3条原则结构体的总大小为结构体最宽基本类型成员大小的整数倍
这里,最宽的类型是name(8个字节,指针地址),实际长度20补全之后,为最终长度为24。
|————-name —- -|
name,8字节
|—age——|—height—| age和height
|—weight-|—————| weight和4个空白字节
.+

.|下面的结构体,实际占用的内存空间是多少?为什么?

struct student
{
int num;
char name[5];

  1. short score;

};

.|此时sizeof(struct student) = 12, 其数据对齐如下图:
需要满足第二原则,每个元素的偏移量必须是其大小的整数倍,比如这里的short大小是2,如果直接跟在char后面,则不符合该原则,只能在char后填充一个空白,再来对齐。
image.png
.+

.|下面的代码是否可以正常执行?效果是什么?注意事项是什么?

struct Foo {
char a;
int b;
}foo1,foo2;
int main()
{
foo1.a = ‘a’;
foo1.b = 1;

  1. foo2=foo1;<br /> printf("%c %d\n", foo2.a, foo2.b);<br /> return 0;<br />}

.|可以正常运行,效果是将foo1的值复制给了foo2。
注意事项:复制是浅复制,如果有指针,也会原样将指针赋值过去。
image.png
从上面的汇编代码可以看出,结构体对结构体的赋值操作,其实,就是将源结构体对应的内存,拷贝到目的结构体中。
此处,结构体的大小是8,所以使用movq一次就可以将全部的数据拷贝过去。