C++结构体字节对齐

虽然内存是以自己为单位的,但大部分计算机CPU在处理内存时,并不会直接以字节为单位。处理为了提高读取速度和减少出错几率,通常会以2字节、4字节、8字节、16字节甚至32字节为单位来存取内存,我们将上述这些存取单位称为内存存取粒度。关于更详细的内存对齐原理,这里不做详细赘述,可以参考这篇文章内存对齐

原文地址快捷方式 -->

有效对齐值

结构体中最大字节数成员的长度和对齐模数中较小的那个值。具体参照如下表达式

有效对齐值 = min{ 结构体重最大成员长度, 对齐模数 }

对齐模数:每个特定平台编译器都有自己默认的对齐系数(也称对齐模数),比如GCC中可默认对齐模数是4(#pragma pack(4)),用户也可以通过预编译指令#pragma pack(x)来指定对齐模数,x可以是1、2、4、8、16等来指定这一对齐模数

内存对齐规则

内部对齐(偏移量对齐):结构体第一个成员的偏移量(offset)为0,以后每个成员相对于结构体首地址的 offset 都是该成员大小与有效对齐值中较小那个值的整数倍,如有需要编译器会在成员之间加上填充字节

偏移量 offset = min { 当前成员长度, 有效对齐值 } 的整数倍

结构体第一个成员的偏移量offset为0,以后的每一个成员相对于结构体首地址的offset都是该成员大小与有效对齐值中较小的那个

外部对齐(结构体整体对齐):结构体的总大小为 有效对齐值 的整数倍,如有需要编译器会在最末一个成员之后加上填充字节

结构体的总大小 = 有效对齐值 的整数倍

实际案例

以下下案例结果统一测试方式

int main(int argc, const char * argv[]) {
    NSLog(@"%lu", sizeof(s));
    return 0;
}

案例具体分析

// 默认对齐模数:4
struct {
  //4   offset = 0,占4位 [count = 4]
  int x;  
  //1       偏移1的倍数,前4个字节(0-1-2-3)被占用,偏移1的倍数从4开始站一位 offset = 4 [count = 5]
  char y; 
} s;
// 4+1 + (3) = 8
// 默认对齐模数:4
struct {
  // 4    offset = 0,占4位 [count = 4]
  int i;   
  // 1    偏移1的倍数,前4个字节(0-1-2-3)被占用,偏移1的倍数从4开始站一位 offset = 4 [count = 5]
  char c1; 
  // 1    偏移1的倍数,前5个字节(0-1-2-3)+(4)被占用,偏移1的倍数从4开始站一位 offset = 5 [count = 6]
  char c2; 
} s;
// 4+1+1 + (2) = 8
// 默认对齐模数:4
struct {
  //1 offset = 0,占1位 [count = 1]
  char c1; 
  //4 偏移4的倍数,前1个字节(0)被占用,偏移4的倍数前边填充(1-2-3),从4开始站一位 offset = 4 [count = 8]
  int i;   
  //1 偏移1的倍数,前8个字节(0-1-2-3)+(4-5-6-7)被占用,偏移1的倍数 offset = 8 [count = 9]
  char c2; 
} s;
// 1+(3)+4+1 + (3) = 12
// 有效对齐值:4
struct {
  char c1; // 1     offset = 0,占1位 [count = 1]
  char c2; // 1     offset = 1,占1位 [count = 2]
  int i;   // 4     offset = 4,占1位 [count = 8]
} s;
// 1+ 1 + (2) + 4 = 8

参考文献

C/C++内存对齐详解

内存对齐

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 为什么要进行内存对齐 1.为了cpu读取更快使CPU的访问内存数据的速度加快,如果一个内存的数据是经过对齐的,那么...
    黑夜no烟丝阅读 876评论 0 2
  • 想要计算结构体大小,必须先掌握结构体内存对齐规则: 1.第一个成员在与结构体变量偏移量为0的地址处。2.其他成员变...
    saygoodbye_e92e阅读 891评论 1 0
  • 例子 定义两个成员个数相同(3个成员)且成员类型相同(int、char、short)的但是成员顺序不同的两个结构体...
    owl207阅读 369评论 0 0
  • 原文:https://blog.csdn.net/IT_Quanwudi/article/details/8052...
    介和阅读 1,485评论 0 0
  • 转载 结构体对齐详解 结构体数据成员对齐的意义 许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会...
    erU阅读 470评论 0 3