结构体内存对齐规则

简介: 结构体内存对齐规则

偏移量

首先我们先来看这样的一段代码

struct test1 {

  char i;
  char a;
  double c;

};

struct test2 {
  
  char c;
  double a;
  char b;
  
};

int main()
{
  printf("%d ",sizeof(struct test1));
  printf("%d ", sizeof(struct test2));
  return 0;
}

你认为结构体test1与test2的大小会一样吗?下面给出运行结果:

可以发现,test1与test2中的变量类型是一样的,为啥大小就不一样了呢?其实在结构体存储中是按照一定规则进行存储的,并不是连续进行存储的!它们的存储是根据偏移量以及对齐数来进行存储的!!!


偏移量:我们以结构体存储的位置作为参考点(标记作为0位置开始),之后的地址距离这个参考点的距离我们称之为偏移量!

偏移量的计算

首先我们需要包含头文件

#include <stddef.h>

代码如下:

struct test2 {
  
  char c;
  double a;
  char b;
  
};


int main()
{
  printf("%d ", offsetof(struct test2, a));
  return 0;
}

运行结果如下:

注:第一个参数是结构体,第二个参数是结构体里面的变量

存储规定

规定:
1 结构体中的第一个变量存储位置的偏移量为0,之后在进行类型存储
2 从第二个变量开始,我们取该类型的对齐数(该类型的大小和编译器中的默认对齐数中取最小
的那个),然后从偏移量是最小对齐数的倍数的位置开始存放数据!
3 所有变量存储完毕之后,所占的字节数必须是各个变量中的那个对齐数中最大的那个数的倍数!

注:在vs中给出对齐数是8,gcc环境下的对齐数就是类型的大小!我们以vs为例!

图解test1:

图解test2:


嵌套结构体

结合上文,我们再来看这样一段代码:

struct test3 {
  char a;
  struct test1;
  int x;
};

int main()
{
  printf("%d\n", sizeof(struct test3));
  return 0;
}

这段代码的运行结果又是多少呢?

运行结果如下:

图解如下:

大小端存储

我们是以字节为单位,讨论数据在内存中的存储顺序!

由计算机中数据的存储方式我们知道(以补码的形式来存储),dd是低字节的内容:

由此我们可以得出大小端村粗方式的定义:

大端存储方式:高字节的内容放到低地址处我们称为大端存储序,反之,则为小端存储序!

如何判断一个机器是大端存储还是小端村粗呢?可以参考以下代码的编写:

int main()
{
  int x = 1;
  char* p = (char*)&x;
  printf("%d", *p);
  return 0;
}

如果p打印出来是1,说明是小端否则为大端,这里主要截取了x中的一个字节进行判断即可!

目录
相关文章
|
6月前
|
编译器 Linux C语言
结构体内存对齐
结构体内存对齐
53 0
|
6月前
|
编译器 Linux C语言
详解结构体内存对齐及结构体如何实现位段~
详解结构体内存对齐及结构体如何实现位段~
|
编译器 C语言 C++
C/C++内存对齐规则(结构体、联合体、类)
C/C++内存对齐规则(结构体、联合体、类)
|
编译器 Linux C语言
什么是结构体和结构体的对齐规则
什么是结构体,为什么会用到结构体?C语言本身存在一些内置数据类型(比如int char float double 数组等),但这些不能满足我们的需要,我们创建了结构体来自定义自己需要的类型。
107 0
|
6月前
|
存储 编译器 Linux
匿名结构体类型、结构体的自引用、结构体的内存对齐以及结构体传参
匿名结构体类型、结构体的自引用、结构体的内存对齐以及结构体传参
|
5月前
|
存储 编译器 C语言
C语言学习记录——结构体(声明、初始化、自引用、内存对齐、结构体设计、修改默认对齐数、结构体传参)一
C语言学习记录——结构体(声明、初始化、自引用、内存对齐、结构体设计、修改默认对齐数、结构体传参)一
60 2
|
5月前
|
编译器 Linux C语言
C语言学习记录——结构体(声明、初始化、自引用、内存对齐、结构体设计、修改默认对齐数、结构体传参)二
C语言学习记录——结构体(声明、初始化、自引用、内存对齐、结构体设计、修改默认对齐数、结构体传参)二
52 1
|
编译器 C++
计算结构体大小:内存对齐详解
计算结构体大小:内存对齐详解
202 0
|
编译器 Linux C++
结构体的内存对齐
结构体的内存对齐
|
编译器 C++
自定义类型之结构体的基础和进阶(有关位段、结构体自引用、嵌套、内存对齐、修改对齐数、结构体的传参、和offsetof宏的使用)
一、结构体基础知识 二、结构体的进阶(有关结构体的自引用,嵌套,内存对齐和内存设计) (一、)首先是结构体的嵌套 (二、)结构体的自引用 (三、)结构体的内存对齐(如何计算结构体的所占内存大小) (四、)如何修改默认对齐数 三、offsetof的意思 四、结构体的传参 五、位段的使用和注意 总结: