热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c++基础知识(六)结构体字节对齐

我们在使用结构体的时候,有没有发现这样的情况,用sizeof(结构体)算出来的内存字节数与结构体里面的数据所占内存字节数总和不匹配。比如以下:

我们在使用结构体的时候,有没有发现这样的情况,用sizeof(结构体)算出来的内存字节数与结构体里面的数据所占内存字节数总和不匹配。

比如以下:

struct A
{
char a='0';//占用1个字节
int b=0;//占用4个字节
short c=0;//占用2个字节
};
本来总共应该是7个字节
但是用sizeof(结构体)算出来却是12个字节

今天我们来看看到底是怎么回事呢?原来啊,是编译器帮我们做了字节对齐。做字节对齐的目的是提高内存的访问效率。

比如32位CPU,每个总线周期都是偶数的地址开始访问读取32位的数据,但是如果数据不是按从偶数开始放置的,则读取则需要两个总线周期才能读到想要的数据。因此需要在内存存放数据时做内存对齐。

内存对齐需要遵守两个基本原则:

1、对于结构体的成员,第一个数据偏移地址为0,后面的数据的偏移量需要是其所占内存大小的整数倍。否则的话就需要进行填充字节数。

    举栗子:

    比如结构体A,很明显第一个成员为a,所以它的偏移地址为0,按照该原则,b占用是4个字节,所以b相对于a的偏移地址必须是4个整数倍,则最小为4,因为a占用1个字节,所以需要在a,b之间填充3个字节来进行字节内存对齐。同理,b的便宜地址变为了4,b本身占4个字节。b的地址为4----8,c的偏移地址就为8,本身占2个字节,偏移量是所占大小的4倍,不需要填充。

2、结构体所有数据内存对齐后,但是结构体也需要内存对齐,其整个结构体内存大小必须是结构体内中数据所占内存最大的整数倍。

   同样看结构体A,从1中我们知道a,b之间填充了3个字节,bc没有填充,总共占据了1+3+4+2=10个字节。根据原则2,结构体大小必须为4(因为该结构体数据中最大占4个字节)倍数,所以末尾再填充两个字节,总共是12个字节。

3、如果程序中有#pragma pack(n) 预编译指令,则所有成员对齐以n字节为准(即偏移量为N的整数倍),不在考虑当前类型以及最大结构体类型。



推荐阅读
author-avatar
沉睡森林
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有