C语言中的内存对齐
最近看了好多,也编了好多C语言的浩强哥书后的题,总觉的很不爽,真的真的好怀念linux驱动的代码,好怀念那下划线,那结构体,虽然自己还很菜。
同时看了一遍陈正冲老师的C语言深度剖析,收益很多,又把唐老师的视频复习了一部分,感觉收获更多。
这阶段一直想写一篇博客,其实有好多东西,先写一下C语言中的内存对齐吧。
大家都知道,在C语言中定义一个变量,char是占用一个字节的,int占用四个字节,float占用四个字节,double占用八个字节,short占用两个字节,long int占用四个字节,long long神马的是64位机器用的,暂时不讨论。
上面说基本的数据类型所占用的字节数,程序的测试咱们printf一下(由于是菜鸟,所以咱们就不玩F8,F9的问题了)。程序如下:
#include<stdio.h> int main(void)
{
char a;
short b;
int c;
long int d;
double e;
float f; printf ("%d,%d,%d,%d,%d,%d\n",sizeof (a),sizeof (b),sizeof (c),sizeof (d),sizeof (e),sizeof (f));
return 1;
}
好了,我们可以知道这些数据类型占用的字节空间了,那么现在提出一个问题。
struct student
{
short s;
long b;
}stu;
当我们以4字节的方式编译的时候,请问printf("%d",sizeof(stu));
我一直都认为这个打印的值是6,因为很明显嘛,short是两个字节的,long是四个字节的,所以打印出来的大小就是6个字节嘛。那好,请在VC下编译测试一下吧。
结果出来的是8!!!
出乎意料了,这就是内存对齐。
内存对齐的意义在于:处理器是以规定的字节数进行读取字节数的,我们编译的是以4字节读取字节数,这就是问题的所在。而且,读取的块的大小必须是2的N次幂。
下面我们解释一下,上面那个结构体打印出来的大小是8的原因。
原因:short类型占用两个字节,四个字节是一块的情况下,那么当一个short类型占用两个字节以后还剩下两个字节,但是接下来我们要存储的是四个字节的long型,如果按照打印六的话,那么我们的处理的取值将会蒙圈,所以实际上编译器把这两个数据分配的空间是short占用两个字节后空出两个字节的位置,这样完成了一个四个字节的块,然后接下来的一个long型占用四个字节,这样完成了两个块,所以我们打印出来的是8 。空说估计一会自己都晕了,所以画个图:
同时还要说一下内存的对齐的规则:
①必须要按照编译器指定的字节数进行读取,同时还要考虑怎么样才可以使编译器读取数据最快捷。
②另外最后占用的字节数必须是整个结构体中字节数最大数据类型的整数倍。
还有一些其他规则,下面再进行介绍。
一个结构体的问题差不多了吧?那么再看一个:
#include <stdio.h> struct student
{
short s;
long b;
}stu1; struct teacher
{
char c;
struct student stu1;
double e;
}stu2; int main()
{
printf("%d,%d\n",sizeof(stu1),sizeof(stu2));
}
咱们还是打印,那么打印出来的是多少呢?
这里说个插曲,在VC中默认的是8位编译,这个时候打印出来的是8和24,在linux下的GCC编译,打印出来的是8和20 。一直认为VC是4位编译,所以走了一些弯路,后来使用宏条件判断才知道VC是4位编译。下面分别说一下这种结构体嵌套结构体的内存对齐。
上面说的是4位的,那么这里我们还说继续先说4位的。
打印20的原因:
先说一下第二个结构体的第一个成员char,占用的是一个字节。第一个结构体的第一个成员short占用两个字节,第二个成员占用四个字节。好了,暂停一下,我这个时候我就疑惑了,为什么char和short不在一个四字节的块中呢,这样编译器也可以按照四字节进行很快速的读取啊?但是这个时候应该考虑的是,第一个结构体已经被编译器分配好了一个完整的空间,所以这个short是不可以并到第一个结构体中的。回到主题,第一个char单独占用一个字节的四字节的块,第一个结构体占用连个四字节的块,double为8字节,占用两个四字节的块,最后占用的是五个四字节的块。所以打印20 。
上图:
下面说一下当按照8字节进行编译的时候打印出24的原因。(虽然是8字节进行编译的,但是读取的还是按照四个字节进行读取的,这样的话前面说的原则仍然成立。)
原因如下:第一个char占用了一个字节,但是按照8字节存储,按照4字节读取,所以char占用了8字节前面的4字节,后面的四个字节被short占用,这样也完成了处理器最快速度读取并且没有破坏第一个结构体的整体性。剩下的一个一个long占用了一个四字节,我的同学说这个八字节的块要空出来四个,因为不可以把后来的double拆开,但是我认为这么解释不是很合理,我也不清楚原因是什么,所以暂时搁置。
上图:
先说这么多吧,这里面还有一些小东西,太晚了,各位建军节快乐吧,我明天还要继续我苦逼的实训道路。
C语言中的内存对齐的更多相关文章
- C语言中的内存对齐问题
问题 突然收到了一个问题: #include<stdio.h> #include <math.h> struct icd { int a; //4 char b; //1 do ...
- C语言中的内存压缩技术
C语言中的内存压缩技术 前言 在整个研究生阶段我都在参与一个LTE协议栈实现的项目,在这个项目中,我们利用一个自己编写的有限状态机框架将协议栈中每一层实现为一个内核模块.我们知道,在编写内核代码时需要 ...
- C语言中结构体对齐问题
C语言中结构体对齐问题 收藏 关于C语言中的结构体对齐问题 1,比如: struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B; ...
- C++继承体系中的内存对齐
本篇随笔讨论一个比较冷门的知识,继承结构中内存对齐的问题,如今内存越来越大也越来越便宜,大部分人都已经不再关注内存对齐的问题了.但是作为一个有追求的技术人员,实现功能永远都是最基本的要求,把代码优化到 ...
- C语言中的内存分配与释放
C语言中的内存分配与释放 对C语言一直都是抱着学习的态度,很多都不懂,今天突然被问道C语言的内存分配问题,说了一些自己知道的,但感觉回答的并不完善,所以才有这篇笔记,总结一下C语言中内存分配的主要内容 ...
- C语言中的内存管理
开始陆续的发一下唐老师视频的笔记吧,顺便带一些正冲哥书的的内容.不能一下都发出来,因为内容发多了自己也受不了,而且发的都是学习视频时候的一些笔记,可能会有一些问题不是很清晰. 先说一下C语言中的内存管 ...
- C语言中动态内存分配的本质是什么?
摘要:C语言中比较重要的就是指针,它可以用来链表操作,谈到链表,很多时候为此分配内存采用动态分配而不是静态分配. 本文分享自华为云社区<[云驻共创]C语言中动态内存分配的本质>,作者: G ...
- windev中的内存机制及其与C语言中的内存指针相似性(一)
windev中的内存机制,是初入windev世界必须要越过的一道高山,以下我的理解和经验未必都对,如有错误或遗漏,以后再纠正或补充!另外,以下内容,咱先谈应用,再说对机制的认识和理解. 一.新建表单, ...
- C语言中的内存相关问题
内存是用来存储数据与程序的,对我们写程序来说非常重要.所以内存对程序来说几乎是本质需求.越简单的程序需要越少的内存,而越庞大越复杂的程序需要更多的内存. 注意:在嵌入式系统中有ROM和RAM两类内存, ...
随机推荐
- Java虚拟机类型卸载和类型更新解析(转)
转自:http://www.blogjava.net/zhuxing/archive/2008/07/24/217285.html [摘要] 前面系统讨论过java 类型加载(loa ...
- 解决Gradle minifyEnabled无法找到错误
Android studio最新版0.9支持proguard minify,shrinkResources ,尝试了下,提示找不到minifyEnabled方法 Error:(29, 0) Gradl ...
- oracle当需要commit
今天oracle的SQL plus 运行该删除和查询操作,然后PL/SQL还运行查询.相同的句子,结果是不一样的.我郁闷很大,然后,突然想到这可能对双方造成由数据不一致,为什么不一致呢.就是没用com ...
- react学习笔记2--练习Demos
准备工作 # 0.react核心库 <script src="../build/react.js"></script> # 将JSX 语法转为 JavaSc ...
- HDU Today (图论)
经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强.这时候,XHD夫妇也退居了二线,并在风景秀美的诸暨市浬 ...
- GPS转换为百度坐标
原文地址:http://www.cnblogs.com/zhaohuionly/archive/2013/06/18/3142623.html 最近在做一个关于手机定位的小应用,需求是这样的,用户通过 ...
- Codeforces Round #248 (Div. 2) (ABCD解决问题的方法)
比赛链接:http://codeforces.com/contest/433 A. Kitahara Haruki's Gift time limit per test:1 second memory ...
- HDU 2612 -Find a way (注重细节BFS)
主题链接:Find a Way 题目不难,前几天做,当时准备写双向BFS的,后来处理细节上出了点问题,赶上点事搁置了.今天晚上重写的,没用双向,用了两次BFS搜索,和双向BFS 道理差点儿相同.仅仅是 ...
- svnclient本地化和异常处理
svn中国本土化,首次安装client.然后下载语言包的相应版本,然后将语言设置为英文! 我碰到汉化失败的案例:client与语言包版本号不匹配 之前安装的语言包: 下载相应语言包: 假设之前安装了, ...
- 西门子PLC学习笔记8-(计时器)
计时器port这包括:信号输入.时间.复位信号.出口.[计时器剩余时间(BI二进制表示法.BCD码表示)其输出被存储MW] 定时器包括::S_PULSE(脉冲定时器).S_PEXT(延时脉冲定时器). ...