本文參考了《高质量程序设计指南——C++/C语言》一书

有不妥之处恳请指正

一、自然对齐

某些基于RISC(精简指令集)的CPU比方SPARC、PowerPC等。採用高字节和高字在低地址存放、低字节和低字在高地址存放的大端模式存储。而且把最高字节的地址作为变量的首地址。

在这样的自然的存储格式中,要求变量在内存中的存放位置必须自然对齐,否则CPU会报告异常。所谓自然对齐,就是基本数据类型(主要是short、int、double)的变量不能简单地存储于内存中的随意地址处。它们的起始地址必须可以被它们的大小整除。

比如。在32位平台下,int和指针类型变量的地址应该能被4整除。而short变量的地址应该都是偶数,bool和char则没有要求。所以。基于这样的CPU架构的平台,编译器将依照自然对齐的要求来为每一个变量生成逻辑地址,C++/C编译器亦如此。

而Intel系列CPU採用小端模式来存放基本类型变量,即低字节和低字在低地址存放、高字节和高字在高地址存放。而且把最低字节的地址作为变量的首地址。在Intel系列CPU这样的硬件平台上。并不严格要求基本数据类型变量在内存中必须自然对齐,相同也不会要求复合类型变量必须自然对齐。可是VC++在处理程序时,为了提高CPU的处理速度,对复合类型变量做了成员对齐处理。

二、成员对齐

VC++在处理复合数据类型成员变量时默认遵循下面三种原则:

(1)    复合类型对象的首地址要能被占用字节数最多的成员变量的字节数整除。

(2)    复合类型对象占用的内存空间大小要能被占用字节数最多的成员变量的字节数整除。

(3)    各成员变量存放的起始地址相对于复合结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。

举比例如以下:

struct exm

{

bool a;

double b;

bool c;

};

它是怎么存储的?

首先,在内存中找一个能被8整除的起始地址。然后分配24个字节。

为什么是24个而不是10个?或者是16个?

这是由于原则(3)的缘故,变量b占8个字节,那么它相对于结构的起始地址的偏移量必须为8的倍数,因此尽管a仅仅占一个字节,但后面会补上7个字节。

那么为什么变量c也占8个字节啊?这是由于原则(2)的缘故。由于在结构体exm中。占用字节数最多的是变量b。8个字节,所以exm占用的空间大小应能被8整除,如今a和b已经占用16个字节了,而c至少要占用一个字节,因此会在c后补上7个字节,变成24个字节。

把exm成员调换一下。变为:

struct exm

{

double b。

bool a。

bool c;

};

它的大小就变成16个字节了。

当然,我们也能够在程序中指定对齐方式。这时上述原则将不再成立。假设在程序中指定对齐方式。则对于复合结构中的变量,假设占用空间不足指定对齐字节。且假设依照默认对齐方式占用的空间将比指定的对齐方式大,则将按指定对齐方式补足,比如:

#pragmapack(4) //依照4字节边界对齐

struct exm

{

bool a;

double b;

bool c;

};

在VS2010中,它占用16个字节空间。

分析:变量a假设依照默认对齐方式要占8位,但它本身是bool型变量,占一位,指定对齐方式为4字节对齐,则a将被补齐为4字节。同理变量c也一样。

把exm成员换一下位置:

#pragmapack(4) //依照4字节边界对齐

struct exm

{

double b;

bool a;

bool c。

};

则exm占12位。

C++成员对齐方式探讨的更多相关文章

  1. 关于arm处理器 内存编址模式 与 字节对齐方式 (转)

    转自:http://bavon.bokee.com/5429805.html 在x86+Linux上写的程序,在PC机上运行得很好.可是使用ARM的gcc进行交叉编译,再送到DaVinci目标板上运行 ...

  2. C# 使用 StructLayoutAttribute 时 C# /C++ 内存空间分配与成员对齐问题

    1. 使用场景 公共语言运行时控制数据字段的类或结构在托管内存中的物理布局.但是,如果想要将类型传递到非托管代码,需要使用 StructLayout 属性. 2. 内存分配问题. 如果不显示的设置内存 ...

  3. C语言中内存对齐方式

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

  4. struct的成员对齐问题-结构体实际大小问题

    struct的成员对齐 注意:为了方便说明,等号左边是每个数据单独所占长度,右边是最终空间大小,以字节为单位. 一.什么时间存在对其问题:(32位机对齐方式是按照4字节对其的,以下所有试验都是在32位 ...

  5. C++ 学习笔记3,struct长度測试,struct存储时的对齐方式

    之所以专门为struct的长度写一篇測试,是由于原来c++对于struct的变量, 在分配内存的时候,c++对struct有一种特殊的存储机制. 看以下的測试: 一.在Windows7 32bit , ...

  6. 从零开始学C++之IO流类库(四):输出流格式化(以操纵子方式格式化 以ios类成员函数方式格式化)

    一.以操纵子方式格式化 数据输入输出的格式控制使用系统头文件<iomanip>中提供的操纵符.把它们作为插入操作符<<的输出对象即可.如setiosflags.setw.set ...

  7. 输出流格式化(以操纵子方式格式化,以ios类成员函数方式格式化)

    一.以操纵子方式格式化 数据输入输出的格式控制使用系统头文件<iomanip>中提供的操纵符.把它们作为插入操作符<<的输出对象即可.如setiosflags.setw.set ...

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

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

  9. C/C++ struct定义、声明、对齐方式

    一.定义/声明方式 第一种:仅有结构体名,不定义/声明变量 struct MyStruct {  int i:     char a[10];     double b; }:第二种:有结构体名,并声 ...

随机推荐

  1. Python批量下载电视剧电影--自己动手丰衣足食

    前言 为了看美剧<天蝎>,在电影天堂找到了,于是就想下载下来好好欣赏. 废话不说了,直接上代码. 代码 import requests,re,os,time url = "htt ...

  2. IE/firefox/chrome 每次都刷新

    IE FIREFOX 1.在firefox的地址栏上输入about:config回车2.找到browser.cache.check_doc_frequency选项,双击将3改成1保存即可. 那么这个选 ...

  3. STA之Concepts (2)

    3 Skew between signals Skew is the difference in timing between two or more signals, maybe data, clo ...

  4. HDU_2079_(01背包)(dfs)

    选课时间(题目已修改,注意读题) Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. 梦想Android版CAD控件2018.7.26更新

    下载地址: http://www.mxdraw.com/ndetail_109.html 1. 增加所有接口CHM帮助文档 2. 增加得到当前打开文件函数 3. 读写CAD扩展记录接口 4. 读写属性 ...

  6. 09Microsoft SQL Server 表数据插入,更新,删除

    Microsoft SQL Server 表数据插入,更新,删除 向表中插入数据 INSERT INTO insert into tb1 values(0004,'张凤凤') insert into ...

  7. share——Alpha版(内部测试版)发布

    我们产品的下载二维码: 使用说明: 后期会进行更新,文件下载位置

  8. nginx代理标准配置

    #nginx开启的进程数worker_processes   4;     #4核CPU   #定义全局错误日志定义类型,[debug|info|notice|warn|crit]error_log  ...

  9. Bazinga HDU 5510 Bazinga(双指针)

    Bazinga HDU 5510 Bazinga(双指针) 题链 解法:对于串i来说,如果串i是不符合的,那么代表串i之前的字符串都是i的子串,那么我们求一个新的i(定义为ti),如果i是ti 的子串 ...

  10. PAT 1130 Infix Expression

    Given a syntax tree (binary), you are supposed to output the corresponding infix expression, with pa ...