zoukankan      html  css  js  c++  java
  • C/C++ 结构体成员在内存中的对齐规则(转载)

    这几天在看王艳平的《windows 程序设计》,第5章讲解了MFC框架是怎么管理窗口句柄到窗口实例之间的映射,用到了两个类CPlex和CMapPtrToPtr,用于管理内存分配的类(避免因为大量地、频繁地创建窗口对象导致内存碎片的产生)。CMapPtrToPtr类用到了关联结构体

    CAssoc,其中有好多对指针类型的转换,感觉对结构体了解不够。特别是成员的对齐方式,跟我猜测的完全不同,花了点时间搞清楚了。在跟朋友一起吃饭还有时间,就顺手写下来,供大家参考:

    首先明白几个概念:

    1、结构体成员的对齐字节数:可以是n=(1,2,4,8,16);VC编译器默认是8,可以打开工程设置->C/C++->Code Generation,可以看到Struct Member Alignment的值为8;

    2、成员所占内存空间的字节数,sizeof(int) = 4,sizeof(short)=2; 设每个成员的内存字节数为:Len

    3、成员的偏移字节数,相对于结构体的首地址;

    接下来有3条规则:

    1、结构体变量的起始地址,也就是第一个成员的地址:为Max(Len) 的整数倍;

    2、每个成员的偏移量为:Min(n,Len) 的整数倍;

    3、整个结构体占用的空间为:Min( n,Max(Len) ) 的整数倍;

    下面看两个例子:

     1 #include <iomanip>
     2 #include <iostream>
     3 using namespace std;
     4 
     5 #pragma pack(push)
     6 #pragma pack(2)  //设置默认对齐字节数
     7 struct MyInfo
     8 {
     9     
    10     char age;
    11     int sn;
    12     char sex;
    13 };
    14 #pragma pack(pop)
    15 
    16 int main(int argc, char* argv[])
    17 {
    18     MyInfo na;
    19     cout<<setw(10)<<"&na.age:"<<(void*)&na.age<<endl;
    20     cout<<setw(10)<<"&na.sn:"<<(void*)&na.sn<<endl;
    21     cout<<setw(10)<<"&na.sex:"<<(void*)&na.sex<<endl;
    22     cout<<setw(10)<<"sizeof(na):"<<sizeof(na)<<endl;
    23     return 0;
    24 }

    规则1,2,3均符合:首地址是4的整数倍;第二个成员偏移量为:Min(2,4) = 2的整数倍;总长度为8,是Min( 2,Max(Len) ) = 4的整数倍,第三个成员后有1 Byte的填充。

    结果为:

     1 #include <iomanip>
     2 #include <iostream>
     3 using namespace std;
     4 
     5 #pragma pack(push)
     6 #pragma pack(8)  //设置默认对齐字节数
     7 struct MyInfo
     8 {
     9     
    10     char age;
    11     int sn;
    12     char sex;
    13 };
    14 #pragma pack(pop)
    15 
    16 int main(int argc, char* argv[])
    17 {
    18     MyInfo na;
    19     cout<<setw(10)<<"&na.age:"<<(void*)&na.age<<endl;
    20     cout<<setw(10)<<"&na.sn:"<<(void*)&na.sn<<endl;
    21     cout<<setw(10)<<"&na.sex:"<<(void*)&na.sex<<endl;
    22     cout<<setw(10)<<"sizeof(na):"<<sizeof(na)<<endl;
    23     return 0;
    24 }

    转载地址:http://www.cnblogs.com/mm220284/archive/2013/09/21/3332181.html

  • 相关阅读:
    linux之sed用法【转载】
    关于Cookie和Session【转载】
    Oracle分页查询与RowNum
    fstream的用法
    Java:Date、Calendar、Timestamp的区别、相互转换与使用【转载】
    DatabaseMetaData的用法【转载】
    关于SQL的Group By
    【转载】B树、B-树、B+树、B*树都是什么
    Spring的MVC控制器返回ModelMap时,会跳转到什么页面?
    关于jsp中超链接的相对路径
  • 原文地址:https://www.cnblogs.com/stemon/p/3393718.html
Copyright © 2011-2022 走看看