内存对齐?什么是内存对齐?

对于这个问题我们先来看看这样的一个结构体(在32位系统下)

typedef struct Stu1
{char C1;int num1;short S1;}Stu1;

如果我们不知道内存对齐或者不清楚内存对齐时,我们可能这样分析:

C1占一个字节,num1占4个字节,S1占2个字节,所以该结构体占7个字节。

然后我再VS2017上测试发现得到12个字节。

这是为什么呢?这就是由于内存对齐导致的。

为什么会是这样?在解决这个问题时,先来了解一下内存对齐规则

1.结构体的第一个成员在结构体变量偏移量为0的地址处。就是结构体地址和第一个元素的地址的值是一样的,够明了吧。

2.剩下的成员变量要对齐到对齐数的整数倍的地址上。

对齐数听起来很高大上的样子,其实一点也不牛逼,就是一个数罢了,就是该结构体的成员占几个字节就是对齐数,每个成员变量都对应一个对齐数。

最大对齐数就是:编译器的设定对齐数字和结构体中成员占字节最大的那个相比取最小的。怎么样?它就那么回事。

3.结构体的总体大小就是对齐数的整数倍。

4.再嵌套结构体的话,别担心会复杂,你可以这样做就是把嵌套的结构体中变量最大的对齐数和这个结构体相比对齐到最大对齐数上。结构体的整体大小就是所有最大对齐数的整数倍。

现在来看上面的问题:第一个C1开始是对齐数是1就是“1”,但遇到num时就变成了4,所以是“1*** 1111”,再遇到S1发现它对齐数小于num1所以还是4,所以是这样存储:“1*** 1111 11**”。

那么可不可以既提高效率,又能节省空间,有一个小技巧可以解决这样的问题。

再来看一个例子:

typedef struct Stu2
{char C1;short S1;int num1;}Stu2;

和上面的看起来没什么区别,但是注意顺序变了,我们再走一遍看看它是如何进行内存对齐的?

C1开始对齐数是一那就占一个字节,“1”,接着S1占2个字节那就是“1* 11”,接着num1占4个字节那就是:“1*11 1111”。

不过瘾?那再来来几个小试牛刀:

#include<stdio.h>
#include<stdlib.h>typedef struct student1
{char name[1020];double score;int num;long long ShenFenZheng;
}student1;typedef struct student2
{char name[1020];int num;double score;long long ShenFenZheng;
}student2;typedef struct student3
{char name[1024];double score;int num;long long ShenFenZheng;
}student3;typedef struct Stu1
{// student4 stu;char C1;int num1;short S1;}Stu1;typedef struct Stu2
{char C1;short S1;int num1;}Stu2;typedef struct student4
{Stu1 S1;char name[1024];int num;double score;long long ShenFenZheng;
}student4;void Mysizeof()
{printf("%d\n", sizeof(Stu1));//12printf("%d\n", sizeof(Stu2));//8printf("%d\n", sizeof(student3));//1048printf("%d\n", sizeof(student4));//1056printf("%d\n", sizeof(student1));//1048printf("%d\n", sizeof(student2));//1040
}int main()
{Mysizeof();system("pause");return 0;
}

(二)为什么要内存对齐?

1.移植原因:由于所有的硬件平台并不是都能访问任意地址上的任意数据的,有的硬件平台只能在某些地址处取某些特定类型数据,否则抛出异常。

       2.性能原因:上面已经提及,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于是为了访问未对齐的内存,处理器需要做内存访问;而对齐的内存访问进需要一次访问。

结构体的内存对齐就是用空间换时间的做为。(鱼和熊掌不可兼得,哈哈^_^。。。)

补充说明:

1.  每个结构体变量成员在对齐时先按自己的对齐方式对齐,并可以最小化长度。

2.  对齐后的长度必须是该结构体的最大对齐数的整数倍。

3.  字符数组char array[1024],它是以char占的字节进行对齐,而不是数组的长度。

4.  我们也可以修改编译器的默认对齐数。

两种方式

1.  #pragma pack(n)  //n可以设定为需要对齐的数。但注意只能是2的指数倍。

对应的如何取消设定值呢?,在结构体后面加上:#pragma pack()  就可以了,还原为默认值。

2.  另外可以在编译器我以VS为例:在工程的属性页  --->  C/C++  --->  代码生成  --->  结构成员对齐,可以修改默认值。

  珍&源码

初夏小谈:结构体内存对齐详解相关推荐

  1. (C语言)计算结构体大小——结构体内存对齐

    本篇文章计划用简单的方式向大家介绍如何计算结构体大小这一问题 首先我们必须明确一件事,想要计算结构体大小,就不得不了解结构体内存对齐的规则 一.结构体的对齐规则 1.第一个成员在在与结构体变量为0的地 ...

  2. 【C语言】一文搞定如何计算结构体的大小----结构体内存对齐规则

    要搞定如何正确地计算一个结构体的大小,我们就要深刻理解结构体内存对齐规则: 结构体内存对齐规则: 1.结构体的第一个成员永远在结构体起始位置偏移量为0的位置: 2.结构体成员从第二个成员开始,总是放在 ...

  3. 关于C语言中的结构体内存对齐与位段问题

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 结构体的内存对齐与位段 一.结构体的内存对齐 1.为什么会有内存对齐? 2.如何内存对齐 3. 如何在设计结构体的时候,既要 ...

  4. 【APUE】Chapter17 Advanced IPC sign extension 结构体内存对齐

    17.1 Introduction 这一章主要讲了UNIX Domain Sockets这样的进程间通讯方式,并列举了具体的几个例子. 17.2 UNIX Domain Sockets 这是一种特殊s ...

  5. 语言结构体在内存的分布_结构体内存对齐,这篇文章给你彻底搞会!(干货收藏)...

    脚本之家 你与百万开发者在一起 公众号:C语言编程 作者:薛定谔的coding猫 一.内存对齐的原因  1.平台原因(移植原因):一些资料上是这样说的,"不是所有的硬件平台都能访问任意地址上 ...

  6. c#往结构体里面读数据_结构体内存对齐,这回给你彻底搞会!

    一.内存对齐的原因  1.平台原因(移植原因):一些资料上是这样说的,"不是所有的硬件平台都能访问任意地址上的任意数据:某些硬件平台只能在某些特定地址处取某些特定的数据,否则就会抛出硬件异常 ...

  7. c语言 char转int_图文并茂,一文讲透C语言结构体内存对齐

    ↑点击上方蓝色字体,关注"嵌入式软件实战派"获得更多精品干货. (以下有约5000字内容,建议收藏再读,推荐下载源码自行测试以加深理解.) 面试官:你知道C语言的结构体对齐吗? 应 ...

  8. printf打印结构体_工程师:这道题80%初学者都没做对!你确定搞懂结构体内存对齐了?...

    这是工程师面试后的实际经历-- 这道经典.易错的关于C语言结构体内存对齐的题目,你真的会吗: 求32bit环境下以下结构体所占的字节数:typedef struct test_struct{ char ...

  9. 室友利用一把王者的时间就学会了【C语言结构体内存对齐】

    文章目录 一.什么是结构体内存对齐? 二.结构体的对齐规则 结构体内存对齐规则的具体应用 三.为什么会存在内存对齐 总结 提示:以下是本篇文章正文内容,下面案例可供参考 一.什么是结构体内存对齐? 从 ...

最新文章

  1. 如何用FAPROTAX预测微生物群落功能
  2. win7台式电脑怎么连wifi_win7系统怎么设置WiFi共享
  3. 10大Web漏洞扫描器
  4. 快期末考试了好烦躁啊来写点东西
  5. 常用的第三方库(OC)
  6. HDFS源码解析:教你用HDFS客户端写数据
  7. 企业微信发送应用消息的实现
  8. linux系统可以安装Adobe,Ubuntu 64位安装Adobe Reader 9.5.5
  9. 最大流最小割定理 (定理,割集)
  10. 事业单位怎么发送通知短信
  11. python基础-异常处理try-except
  12. Python 内置模块tkinter —— 秒表计时器
  13. MySQL8功能详解——角色
  14. OpenWrt 4G网卡拨号配置
  15. 鸿蒙os系统3.0体验,华为鸿蒙OS系统体验,和安卓系统差距很大,你愿意升级吗?...
  16. 计算机怎么查看网络连接的地址,各种电脑系统如何查看连接路由器的登录地址是多少?...
  17. 充电口 米兔积木机器人_米兔积木 篇三:我与小米积木有个约会之米兔机器人平衡车版...
  18. C语言 自定义字符串拼接函数
  19. ② ESP8266 开发学习笔记_By_GYC 【ESP8266 驱动 ws2812 三原色灯(spi方式 稳定灯光)】
  20. 移动硬盘文件或目录损坏且无法读取解决方法

热门文章

  1. 人工智能时代特征初步显现,主要体现在哪几个方面?
  2. 网页前端监控系统(错误日志,接口监控)的使用
  3. 【技术分享】Win10 wampserver升级安装php7.2.32
  4. 2022最新版WiFi大师专业版小程序独立版4.0.5安装教程
  5. xcopy 复制目录及子目录
  6. Mac上Elasticsearch 安装及PHP使用
  7. MacM1本地navicat无法连接本地docker的mysql。
  8. 计算机系统盘突然爆满,电脑c盘突然爆满是怎么个情况_电脑c盘和d盘的区别
  9. 移动互联网主要的技术标准
  10. 电商中spu和sku是什么?怎么去设计表结构?