c++ 结构体_C++基础知识之结构体字节对齐

一、背景

    计算机存储数据时,是以字节(byte = 8bit)为单位进行存储的,其地址不是随意分配的,而是按一定的规律来存储。

    为什么要要按一定规律来存储数据呢?随机分配地址,紧密排列数据不香吗?

    对于不同硬件平台,其对数据存取的规则存在差异,对于特殊类型的数据需要存储在特殊地址上;对于一些架构CPU需要对存储的数据进行字节对齐,否则会出错,因此会影响数据存取效率。(后期需要大佬辅助补充);

    为什么需要结构体字节对齐?

    结构体即是一些数据的集合,其首地址就是第一个元素地址,如果没有字节对齐,其各个元素紧密相连,这样理论上是没有问题的;但是如果在32位系统上对这样的数据进行读取时,会出现下面这个问题:

6343dd133f571ad99f042c413d3db3b7.png

每次机器只能读取4个字节,这样会把中间数据分割开,进行两次读取,无形中会影响读取数据的效率。甚至会出现数据读取错误。

二、结构体字节对齐规则:

    1.结构体的总长度(sizeof)为结构体中最宽类型的整数倍;

    2.结构体中元素地址到结构体首地址的偏移量为其类型的整数倍;

    3.结构体的首地址是结构体中最宽类型的整数倍(我们一般不用考虑,编译器会自动分配);

    4.当指定对齐参数 n时,每个类型的大小 与n 比较,以小的值为对齐值,进行字节对齐;

    5.当结构体1 中函数结构体2 时,结构体2 首地址按照 结构体2 中最宽类型获取;结构体1 中最宽类型 如果为结构体2,则结构体1的长度应为结构体2宽度的整数倍。

三、结合实例进行验证 

typedef struct{  char a;  double b;  char c;}YCH_TEST1_STRU;typedef struct{  char a;  char b;  double c;}YCH_TEST2_STRU;sizeof(teest1_stru)   :      24test1_stru       :0019F2ACtest1_stru.a    :0019F2ACtest1_stru.b    :0019F2B4test1_stru.c    :0019F2BCa------------b------------c-------------|-8----->|-8---->|1 + sizeof(teest2_stru)   :      16test2_stru       :0019F29Ctest2_stru.a    :0019F29Ctest2_stru.b    :0019F29Dtest2_stru.c    :0019F2A4a--------b-------------c------------|-1--->|1 + 

下面给出一个实例,验证结构体嵌套结构体的字节对齐案例:

#include #include // ---------------------------------------------------using namespace std;// ---------------------------------------------------typedef struct {  char a;  double b;  char c;}YCH_TEST1_STRU;// ------------------------typedef struct {  char a;  YCH_TEST1_STRU b;  int c;}YCH_TEST2_STRU;// ---------------------------------------------------// ---------------------------------------------------int main(){  // ----------------------------------------  YCH_TEST1_STRU test1;  memset(&test1, 0, sizeof(test1));  YCH_TEST2_STRU test2;  memset(&test2, 0, sizeof(test2));  // ----------------------------------------  char str[100] = { 0 };  snprintf(str, 100, "size of test1 : %d", sizeof(test1));  cout << str << endl;  snprintf(str, 100, "size of test2 : %d", sizeof(test2));  cout << str << endl;  // ----------------------------------------  snprintf(str, 100, "addresss of  test2   : %p", &test2);  cout << str << endl;  snprintf(str, 100, "addresss of  test2.a : %p", &test2.a);  cout << str << endl;  snprintf(str, 100, "addresss of  test2.b  :%p", &test2.b);  cout << str << endl;  snprintf(str, 100, "addresss of  test2.c : %p", &test2.c);  cout << str << endl;  // ----------------------------------------  return 0;}// ---------------------------------------------------// ---------------------------------------------------输出:size of test1 : 24size of test2 : 40addresss of  test2   : 011AF758addresss of  test2.a : 011AF758addresss of  test2.b  :011AF760addresss of  test2.c : 011AF778
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值