数据对齐(内存对齐)指该数据所在的地址必须是该数据长度的整数倍。X86CPU能直接访问对齐的数据,当它试图访问未对齐的数据时,会在内部进行一系列的调整,降低运行速度。数据对齐一般出现在结构体和类中,在默认情况下,为了方便对结构体内元素的访问和管理,当结构体内的元素的长度都小于处理器的位数的时候,便以结构体里面最长的数据元素为对齐单位,也就是说,结构体的长度一定是最长的数据元素的整数倍。如果结构体内存在长度大于处理器位数的元素,那么就以处理器的位数为对齐单位。但是结构体内类型相同的连续元素将在连续的空间内,和数组一样(摘录)。

sizeof是C/C++中的一个操作符(不是函数!),其作用是返回对象或类型的所占内存字节数,类型为size_t (该返回值依赖于编译系统,但sizeof(char) == 1 ,此值是确定的)。

一般用法为  sizeof(类型说明符) 或  sizeof(变量名) 。sizeof的计算发生在编译时,所以可以这样用: int array[sizeof(int) * 6] ;

下面以例程详细说明:

注:我的电脑是32位XP系统,使用vs2008编译,sizeof(short) == 2  , sizeof(int) == 4;

 typedef struct{
char a;
short b;
int c;
char d;
}ST_TEST;

上面定义了ST_TEST类型的结构体,其中最长的元素为int类型,所以会以4字节对齐。输出sizeof(ST_TEST)值为12,对齐方式如下:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAANgAAABECAIAAABs5myCAAADgElEQVR4nO2dy3mDMBAGKY2aVAF9qBOa8IUquLgEcsAQPRCO2LVZwszJYIN/NoOQ+VDUTAAGaM4OADBNJRHH3vdjzW4G3zSNH1QiHQrwRU7Ipl1eCyRlVBBx7F3TNIj4sa/TL68F9EWcN3CI+Mmv1Czv2PcGnEZEKRcXceydicYVEaVcWsTBW7nKS0VcuyxN434/s1ZqPtDovXCTuAavPvjr/fCd+4q4FDAq4m55k62it+IKOxf8IbJ9fBmRiINf88/Htsgz9m4+Tj+sS8sego2y7deKDD46S+8q4uCXko69S0QslDf+ZNDibVdY+9p1GIGI0RHH5dirTbKHoArlotxUxKSmPhaxrF52mYn+Lskpfn0R00OONnhjWHB61okYXqriy9M5azaLo7fzdV10Hu+UN7/FGK7ZF/HUSoZl7LquVsRCx2JXxN/KHGgRbyZivLuo5/NfRey6rlLE5AIxBXek3lSqcKXg0pwSdJV3fAoX4776smHB4M01JyFoERet3dpY5T/r8sWgoGnREDEllGjwfzuB56qGH0068tsiJj8Pv4709k3QxAYVC9aFN2tcP4bdQ9f3futjuYx3FjGtypvyzpFcXstChZfVZ7eKn7mhrc3pAXawnO1CIKIUy9kuBCJKsZztQvxJRIAvg4hgAkQEEyAimAARwQSICCZARDCB0fuI8I/ZtAsR68mfQoIaEFGJWhFtDN+0AyKegpXhm3ZAxBOwM3zTDoioRPJ0/rK4Pv+3+ZggvcoVRFQg+U80+WOqaQfSzKP5dkBEJfZH3iRDaRExI7Gr67qpfjhp/PD5fdbE1XknYnnR1HH5cwqYDJtCxJo1iChcs2VXF8CluR6JiKDQIsLMViNXXDQzfNMO4j4iTOn/Tkl+NW+N9bQyfNMO/GoW83xOz6fC63uDiGIej6ltX0q17cHXtwcRNZhdbNvp8Tj4+vYuVogIe8xKyV9DACKCCRARTICIYAJEBBMgIpgAEcEEzE6qAGnlMZidVAHSymMwF58CpJXHQEQFSCuPgYgKkFYeg9lJFSCtPAazkypAWnkMZidVgLTCGAcmhSz0A+8zO+n+NJHWsu2kNRLjyKSQzE6KiNoxDg0nZXbSAqSVxDgyrpnZSTchrTDGkQH2zE6aQ1p5DKODp04PUAVp5TEQUQHSymMgogKklcfgwVgwASKCCRARTICIYIIf1aX+I8O/J7oAAAAASUVORK5CYII=" alt="" />

类中的对齐和结构类似,但是注意:类中如果有静态成员变量,因为静态变量是存放在全局数据区的,而sizeof计算栈中分配的大小,所以是不会将静态变量计算在内的。

对齐这块就说这个多吧,大家可以自己在编译器上多写几个结构试试就会更理解了。

下面再说sizeof的其他使用,依旧看例码:

 char sch_0[] = "";
char sch_1[] = "";
char sch_2[] = "abc\n";
int iarr[] = {}; char *pch_0 = "";
char *pch_1 = "abc\n";
int *parr = &iarr[];

对以上变量使用sizeof,输出依次为 100、11、5、400、4、4、4.

第一行 sch_0 数组,其大小相当于 sizeof(char)*100 ;

第二行 sch_1 数组,未显式指定大小,所以其大小根据字符串内容计算,为“0-9” 10个字符,加上末尾的 '\0' 结束字符,共11个;

第三行 sch_2 数组,同第二行,但是 '\n' 为1个字符(转义字符);

第四行 iarr 数组,大小为 sizeof(int)*100 ;

最后三行的输出都为4,这是因为例如 sizeof(pch_0) 求的是一个指针的大小,换句话说就是求一个地址占多少字节,我们假如pch_o的值为0xFF66AACC,4字节指的就是这个地址值本身,跟这个地址指向什么数据(类型)无关!

再附加一个 strlen :这是一个函数! 获得一个字符串的长度,不包括结尾的空字符(NULL)。 如strlen(sch_0) == 10 ,strlen(pch_1) == 4 ;

strlen只能用于char类型的字符串(数组),若strlen(iaar) ,则会报错。

.

空类所占空间为1,单继承和多继承空类的空间仍为1,虚继承的空类为4.(看到了顺便)

.

.

.

补充一个很简单却有一定迷惑性的例题:

 char var[] = {};
int test(char var[])
{
return sizeof(var);
}

问以上函数输出结果?注意:正确答案是4.因为形参将退化为指针,返回结果就是一个指针的内存大小。它的迷惑性就在于test函数的形参刚好和第一行定义的数组同名,不要被他骗了.....

内存对齐 和 sizeof小结的更多相关文章

  1. 关于sizeof()和内存对齐

    PS补充:枚举类型的字节数为什么为4 百度知道回答: typedef enum e1{ MON, TUE, THI, }e; e1是一个数值,它的允许值范围是: MON,TUE,THI, 它的取值为其 ...

  2. c++编程思想(三)--c++中c 续,重点sizeof和内存对齐

    之前理论性的太多,下面就是代码及理论结合了 1.sizeof()是一个独立运算符,并不是函数,可以让我们知道任何变量字节数,可以顺带学一下struct,union,内存对齐 内存对齐:为了机器指令快速 ...

  3. c++ 通过sizeof运算符看内存对齐

    一.基础数据类型 基础数据类型的sizeof,包括char.short,int,long,float,double 注意:实际数值有所偏差,与系统相关 二.数组及字符串 包括字符数组.字符指针.字符串 ...

  4. 【C语言】字节对齐(内存对齐)

    数据对齐 1.  对齐原则: [原则1]数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma p ...

  5. Go中由WaitGroup引发对内存对齐思考

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的go的源码时14.4 WaitGroup使用大家都会,但是其中是怎么实现的我们 ...

  6. golang内存对齐分析(转载)

    问题 type Part1 struct { a bool b int32 c int8 d int64 e byte } 在开始之前,希望你计算一下 Part1 共占用的大小是多少呢? func m ...

  7. C++内存对齐总结

    大家都知道,C++空类的内存大小为1字节,为了保证其对象拥有彼此独立的内存地址.非空类的大小与类中非静态成员变量和虚函数表的多少有关. 而值得注意的是,类中非静态成员变量的大小与编译器内存对齐的设置有 ...

  8. C/C++: C++位域和内存对齐问题

    1. 位域: 1. 在C中,位域可以写成这样(注:位域的数据类型一律用无符号的,纪律性). struct bitmap { unsigned a : ; unsigned b : ; unsigned ...

  9. C/C++ 知识点1:内存对齐

    预备知识:基本类型占用字节 在32位操作系统和64位操作系统上,基本数据类型分别占多少字节呢? 32位操作系统: char : 1    int :4    short : 2    unsigned ...

随机推荐

  1. miniui datepicker 二次加工

    function onshowpopup(){ $(".mini-calendar-timespinner").css({"width":"180px ...

  2. Excel数据批量导入到数据库2

    1.导包(共3个) 2.jsp <s:form action="ReadExcel.action" method="post" enctype=" ...

  3. Android NDK 初探,生成so文件以及调用so文件方法

    因为最近业务上涉及安全的问题 然后有一些加密解密的方法和key的存储问题 本来想存储到手机里面,但是网上说一般敏感信息不要存储到手机Sdcard上 而且我这个如果从网络建立通信获取的话,又太耗时,所以 ...

  4. C#基础

    .net/dotnet:一般指.NetFramework框架,一种平台,一种技术. c#(sharp):一种编程语言,可以开发基于.net平台的应用. Java:是一种技术,又是一门语言: .net应 ...

  5. C# 中正确实现 IDisposable 接口

    作用 此接口的主要用途是释放非托管资源. 当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存. 但无法预测进行垃圾回收的时间. 另外,垃圾回收器对窗口句柄或打开的文件和流等非托管资源一无所知 ...

  6. 深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)

    上篇文章<深入浅出Mybatis系列(二)---配置简介(mybatis源码篇)>我们通过对mybatis源码的简单分析,可看出,在mybatis配置文件中,在configuration根 ...

  7. YY前端课程4

    1. CSS和HTML一样,也是标记语言 2. CSS有三种样式:嵌入样式.内部样式(行内样式)和外部样式(外部样式表) 3. CSS的语法:选择器+{一个或多个样式} 4. 选择器是为了找到html ...

  8. js的规范写法ES5(自己以后按照这样写)

    1.引号的使用,单引号' ' 优先(如果不是引号嵌套,不要使用双引号) 正常情况:console.log('hello there')        双引号转码: $("<div cl ...

  9. CheckedListBoxControl 实现复选框的单选与多选功能

    由于工作需要,需要实现复选框的单选与多选功能,找了好多资料都不是很全,经过两天苦苦的挖挖挖,终于完成啦O(∩_∩)O哈哈~ 用DEV控件中的CheckedListBoxControl控件,当然VS中的 ...

  10. [并查集] POJ 2236 Wireless Network

    Wireless Network Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 25022   Accepted: 103 ...