原文链接:http://www.cnblogs.com/Miranda-lym/p/5197805.html

struct/class/union内存对齐原则有四个:

1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节, 则要从4的整数倍地址开始存储),基本类型不包括struct/class/uinon。

2).结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部"最宽基本类型成员"的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)。

3).收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的"最宽基本类型成员"的整数倍.不足的要补齐.(基本类型不包括struct/class/uinon)。

4).sizeof(union),以结构里面size最大元素为union的size,因为在某一时刻,union只有一个成员真正存储于该地址。

实例解释:下面以class为代表

No.1

class Data
{
    char c;
    int a;
};

cout << sizeof(Data) << endl;

No.2

class Data
{
    char c;
    double a;
};

cout << sizeof(Data) << endl;

显然程序No.1 输出的结果为 8    No.2 输出的结果为 16 .

No.1最大的数据成员是4bytes,1+4=5,补齐为4的倍数,也就是8。而No.2为8bytes,1+8=9,补齐为8的倍数,也就是16。

No.3

class Data
{
    char c;
    int a;
    char d;
};

cout << sizeof(Data) << endl;

No.4

class Data
{
    char c;
    char d;
    int a;
};

cout << sizeof(Data) << endl;

No.3运行结果为 12

No.4运行结果为 8

class中的数据成员放入内存的时候,内存拿出一个内存块来,数据成员们排队一个一个往里放,遇到太大的,不是把自己劈成两半,能放多少放多少,而是等下一个内存块过来。这样的话,就可以理解为什么No.3,No.4两端的代码输出结果不一样了,因为左边是1+(3)+4+1+(3)=12,而右边是1+1+(2)+4=8。括号中为补齐的bytes。

No.5

class BigData
{
    char array[33];
};

class Data
{
    BigData bd;
    int integer;
    double d;
};

cout << sizeof(BigData) << "   " << sizeof(Data) << endl;

No.6

class BigData
{
    char array[33];
};

class Data
{
    BigData bd;
    double d;
};

cout << sizeof(BigData) << "   " << sizeof(Data) << endl;

No.5和No.6运行结果均为: 48

在默认条件下,内存对齐是以class中最大的那个基本类型为基准的,如果class中有自定义类型,则递归的取其中最大的基本类型来参与比较。在No.5和No.6中内存块一个接一个的过来接走数据成员,一直到第5块的时候,BigData里只剩1个char了,将它放入内存块中,内存块还剩7个bytes,接下来是个int(4bytes),能够放下,所以也进入第5个内存块,这时候内存块还剩3bytes,而接下来是个double(8bytes),放不下,所以要等下一个内存快到来。因此,No.5的Data的size=33+4+(3)+8=48,同理No.6应该是33+(7)+8=48。

顺便提一下Union: 共用体表示几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。在union中,所有的共用体成员共用一个空间,并且同一时间只能储存其中一个成员变量的值。

以上内容部分转载自http://www.cnblogs.com/biyeymyhjob/archive/2012/09/07/2674992.html


拓展:

一、32位操作系统下各种数据类型所占的字节数

1、整型

int                         4字节                      

long int                  4字节

short int                   2字节

unsigned long int     4字节

unsigned short int    2字节

2、字符型

char                          1字节

unsigned char           1字节

3、浮点型

float                              4字节

double                          8字节

long double                  8字节

unsigned long double   8字节

unsigned double           4字节

4、字符串型

string                           32字节

5、指针类型

所有类型的指针都是 4字节 (但是在64位下为8字节)

二、字节对齐原则

在系统默认的对齐方式下:每个成员相对于这个结构体变量地址的偏移量正好是该成员类型所占字节的整数倍,且最终占用字节数为成员类型中最大占用字节数的整数倍。

三、C++类中的数据成员也遵循以上对齐原则,即:

1.在不考虑(或者说在没有)虚函数和虚继承的情况下,sizeof(自定义类)也按照类似上面的方式来计算。

2.但如果一个类拥有虚函数或者虚继承,则在数据成员的基础上相当于多一个指针类型的数据成员(位置在所有数据成员的前面),最后计算时加上即可。

3.静态(static)成员不在计算范围。

[简言之,类的大小与成员变量(非static数据成员变量)和虚函数指针有关(注意:虚函数中有一个指向虚函数列表的指针,无论有多少个虚函数都是占用一个字节的大小)]

4.如果一个类或者结构体不含有任何数据成员,且无虚函数以及虚继承,则sizeof()结构为1。

四、为什么要进行字节对齐?

  《Windows核心编程》里这样说:当CPU访问正确对齐的数据时,它的运行效率最高,当数据大小的数据模数的内存地址是0时,数据是对齐的。例如:WORD值应该是总是从被2除尽的地址开始,而DWORD值应该总是从被4除尽的地址开始,数据对齐不是内存结构的一部分,而是CPU结构的一部分。当CPU试图读取的数值没有正确的对齐时,CPU可以执行两种操作之一:产生一个异常条件;执行多次对齐的内存访问,以便读取完整的未对齐数据,若多次执行内存访问,应用程序的运行速度就会慢。

可参考webary的blog:http://www.cnblogs.com/webary/p/4721017.html

【转】C/C++ struct/class/union内存对齐的更多相关文章

  1. C++:struct和union 内存字节对齐问题

    转自:http://blog.csdn.net/wangyanguiyiyang/article/details/53312049 struct内存对齐问题 1:数据成员对齐规则:结构(struct) ...

  2. Windows下struct和union字节对齐设置以及大小的确定(一 简介和结构体大小的确定)

    在windows下设置字节对齐大小的方式,目前我了解有三种: 1. 在编译程序时候的编译选项  /Zp[n],如 cl /Zp4 表示对齐大小是4字节: 2. 预处理命令   #pragma pack ...

  3. C/C++中的内存对齐 C/C++中的内存对齐

    一.什么是内存对齐.为什么需要内存对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址 ...

  4. C/C++ 内存对齐原则及作用

    struct/class/union内存对齐原则有四个: 1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储 ...

  5. (转)c/c++内存对齐问题

    struct/class/unio内存对齐: http://blog.csdn.net/microsues/article/details/6140329 class函数占用字节数问题: http:/ ...

  6. C/C++中struct/union/class内存对齐

    struct/union/class内存对齐原则有四个: 1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储 ...

  7. <转> Struct 和 Union区别 以及 对内存对齐方式的说明

    转载地址:http://blog.csdn.net/firefly_2002/article/details/7954458 一.Struct 和 Union有下列区别: 1.在存储多个成员信息时,编 ...

  8. C语言中内存对齐规则讨论(struct)

    C语言中内存对齐规则讨论(struct) 对齐: 现代计算机中内存空间都是按着byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地 ...

  9. struct内存对齐1:gcc与VC的差别

    struct内存对齐:gcc与VC的差别 内存对齐是编译器为了便于CPU快速访问而采用的一项技术,对于不同的编译器有不同的处理方法. Win32平台下的微软VC编译器在默认情况下采用如下的对齐规则:  ...

随机推荐

  1. HDU 3078:Network(LCA之tarjan)

    http://acm.hdu.edu.cn/showproblem.php?pid=3078 题意:给出n个点n-1条边m个询问,每个点有个权值,询问中有k,u,v,当k = 0的情况是将u的权值修改 ...

  2. 以雅酷网为实例从技术上说说dedecms的seo优化要注意哪些?

    目前在做雅酷网 ,雅酷卡是雅酷时空公司的产品,我个人感觉用雅酷卡消费还是比较实惠的,而雅酷卡的特色便是雅酷健身卡,很多站长成天的趴电脑上,可以考虑办一张这样的卡,在周末的时候去健身中心活动活动,还是比 ...

  3. cocos2dx lua bug之module 'lsqlite3' not found

    05-27 15:41:01.360: D/cocos2d-x debug info(7261): [LUA-print] -------------------------------------- ...

  4. YTU 2344: 先序遍历二叉树

    原文链接:https://www.dreamwings.cn/ytu2344/2603.html 2344: 先序遍历二叉树 时间限制: 1 Sec  内存限制: 128 MB 提交: 4  解决:  ...

  5. JS 滚动效果

    地址: https://github.com/aamirafridi/jQuery.Marquee <script language="JavaScript" src=&qu ...

  6. Windows上Python3.5安装Scrapy(lxml) 以及与twisted有关错误的解决

    转载于:http://www.cnblogs.com/silverbullet11/p/4966608.html 常用网址: Python 3.5: https://www.python.org/do ...

  7. Android各种获取Context方法

    首先讲一讲这四个函数的区别,后面还有我对context的一些理解区别如下所示: 原文链接http://stackoverflow.com/questions/6854265/getapplicatio ...

  8. NSIS学习记录の----NSIS插件调用

    我们都知道NSIS可以和C或者C++混合编程,方法是NSIS调用C或C++的动态库,那么如何调用呢? 首先我们来创建动态库: // add.cpp : 定义 DLL 应用程序的导出函数. #inclu ...

  9. 2016年12月16日 星期五 --出埃及记 Exodus 21:11

    2016年12月16日 星期五 --出埃及记 Exodus 21:11 If he does not provide her with these three things, she is to go ...

  10. PHP redis负载均衡代码

    <?php /** * This is a Redis exntend class * jay.w */ class RedisClient { public static $instance ...