第二天:字节对齐

本文介绍了C++中的字节对齐概念,包括不同数据类型在不同编译器下所占字节数,以及结构体中字节对齐的规则和影响。通过实例分析了字节对齐如何影响结构体的大小,并探讨了字节对齐的原因和潜在隐患,如内存浪费和地址运算错误。最后提供了相关参考文章链接以深入学习。

一:.h和.cpp的区别
.h包括IDE的库文件和自己写的头文件,有函数和类的声明。
.cpp是源码文件,有函数的实现。编译的时候.h文件起到连接的作用。

二:int,long int,short int所占字节
16位编译器,32和64位有不同标注再中括号中:
char:1个字节
short int:2个字节
int:2个字节 【32和64位是4个字节】
float:4个字节
double:8个字节
long:4个字节 【64位是8个字节】
long long:8个字节
char*(即指针变量): 2个字节 【32位是4个字节(32位的寻址空间是2^32, 即32个bit。同理64位编译器是8个字节)】

参考原文:http://blog.sina.com.cn/s/blog_693ac9f60100q613.html

三:字节对齐

  • 1.抛出问题
    struct{int a; char b;}的大小是多少?答案是8。
  • 2.分析问题
    首先,每种类型的变量的默认对齐长度都是自己的变量长度,比如:char占一个字节,那么对齐长度就是一个字节,int占四个字节,对齐长度就是四个字节,double占八个字节,对齐长度就是8。int的对齐长度为4的实际意义是,int变量必须存储在四的倍数的地址上。
    那么对于struct{char b; int a},其长度是8,因为b虽然只占用1个字节,但是a必须从4的倍数开始存储,因此b后面的3个字节都废掉了。因此一共需要8个字节才能把b和a存下来。
    那么对于struct{int a; char b},其长度还是8!晕菜了!原因如下:
    字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
    1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除。
    2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
    3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
    规则1是控制结构体变量的首地址的,与结构体变量的长度没关系。
    规则2是控制结构体内每个变量的相对地址的,与结构体变量的长度有关系。
    规则3是控制结构体总体长度的,与结构体变量的长度有关系。
    正是由于第三条规则,结构体的长度必须是其最长的变量长度的整数倍,因此在上面的例子中,必须是4的整数倍,因此,是8。
    如果结构体里面嵌套结构体就要注意了,结构体变量的起始地址只是其内部最宽的基本类型的整数倍,而非结构体自身的整数倍,外面结构体的长度,也仅仅是里面最宽的基本类型的长度倍数。
    比如:
struct S1 {
  char c;  // 1个字节
  int i;   // 前面空3个字节,占用4个字节
}; // 刚好8个字节,是4的倍数 
struct S2 { 
  char c1; // 1个字节
  S1 s;  // 前面空3个字节,而不是空7个字节,占用8个字节
  char c2; // 占用1个字节 
}; // 一共13个字节,要成为4的倍数,后面增加3个字节,成为16个字节
  • 3.字节对齐的原因
    ·效率原因,某些平台每次都是从偶地址读数据,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。
  • 4.字节对齐的隐患
    不合理设置变量定义的顺序,可能浪费内存
struct S1 { // 长度为16
    char a;
    int b;
    char c;
    int d;
}
struct S2 { // 长度为12
    char a;
    char c;
    int b;
    int d;   
}

·更多的是在对地址运算时,没有考虑的字节对齐问题

char a;
int b;
int *pb = &a+1; //这样a的地址加1,并不是b的地址,实际上,这行代码,在编译时就出现了ERROR,因为不能把char *的地址赋值给int *的变量
  • 5.参考文章

字节对齐原文作者:
http://www.cnblogs.com/pangxiaodong/archive/2011/05/20/2052049.html
结构体字节对齐问题:
http://blogold.chinaunix.net/u1/49467/showart_424793.html
字节的对齐原理:http://zhengyueyatou.blog.sohu.com/64814717.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值