zoukankan      html  css  js  c++  java
  • #pragma pack(n) 啥时候可以不再忘记?

    已经记过好多遍了------再次用起来还是忘记--------

    悲剧的是被 有些帖子写的那么难以理解-------重新看的时候老被误导---------

    手工贴一篇 ,以后就看这个了。

    来自csdn的帖子:
    主  题:    探讨:内存对齐
    作  者:    typedef_chen ((名未定)(我要骗人))
    等  级:   
    信 誉 值:    100
    所属论坛:    C/C++ C++ 语言
    问题点数:    50
    回复次数:    1
    发表时间:    2005-04-02 22:53:27
      
      
    朋友帖了如下一段代码:
    #pragma pack(4)
    class TestB
    {
    public:
    int aa;
    char a;
    short b;
    char c;
    };
    int nSize = sizeof(TestB);
    这里nSize结果为12,在预料之中。
    
    现在去掉第一个成员变量为如下代码:
    #pragma pack(4)
    class TestC
    {
    public:
    char a;
    short b;
    char c;
    };
    int nSize = sizeof(TestC);
    按照正常的填充方式nSize的结果应该是8,为什么结果显示nSize为6呢?
    
    事实上,很多人对#pragma pack的理解是错误的。
    #pragma pack规定的对齐长度,实际使用的规则是:
    结构,联合,或者类的数据成员,第一个放在偏移为0的地方,以后每个数据成员的对齐,按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
    也就是说,当#pragma pack的值等于或超过所有数据成员长度的时候,这个值的大小将不产生任何效果。
    而结构整体的对齐,则按照结构体中最大的数据成员 和 #pragma pack指定值 之间,较小的那个进行。
    
    具体解释
    #pragma pack(4)
    class TestB
    {
    public:
    int aa; //第一个成员,放在[0,3]偏移的位置,
    char a; //第二个成员,自身长为1,#pragma pack(4),取小值,也就是1,所以这个成员按一字节对齐,放在偏移[4]的位置。
    short b; //第三个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以放在偏移[6,7]的位置。
    char c; //第四个,自身长为1,放在[8]的位置。
    };
    这个类实际占据的内存空间是9字节
    类之间的对齐,是按照类内部最大的成员的长度,和#pragma pack规定的值之中较小的一个对齐的。
    所以这个例子中,类之间对齐的长度是min(sizeof(int),4),也就是4。
    9按照4字节圆整的结果是12,所以sizeof(TestB)是12。
    
    
    如果
    #pragma pack(2)
         class TestB
    {
    public:
    int aa; //第一个成员,放在[0,3]偏移的位置,
    char a; //第二个成员,自身长为1,#pragma pack(4),取小值,也就是1,所以这个成员按一字节对齐,放在偏移[4]的位置。
    short b; //第三个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以放在偏移[6,7]的位置。
    char c; //第四个,自身长为1,放在[8]的位置。
    };
    //可以看出,上面的位置完全没有变化,只是类之间改为按2字节对齐,9按2圆整的结果是10。
    //所以 sizeof(TestB)是10。
    
    最后看原贴:
    现在去掉第一个成员变量为如下代码:
    #pragma pack(4)
    class TestC
    {
    public:
    char a;//第一个成员,放在[0]偏移的位置,
    short b;//第二个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以放在偏移[2,3]的位置。
    char c;//第三个,自身长为1,放在[4]的位置。
    };
    //整个类的大小是5字节,按照min(sizeof(short),4)字节对齐,也就是2字节对齐,结果是6
    //所以sizeof(TestC)是6。 
    
    

    ----------------------------

    自己测试:

    #pragma pack(push)
    //#pragma pack(1)//8
    //#pragma pack(2) //10
    #pragma pack(4) //12, same with default
    struct a1{
    	char a;
    	WORD b;
    	DWORD c;
    	char d;
    };//12
    #pragma pack(pop)
    
    Microsoft Windows XP Professional 2002 Service Pack 3
    VS2008- Microsoft Visual C++ 2008

    Microsoft Visual Studio 2008
    Version 9.0.30729.1 SP
    Microsoft .NET Framework
    Version 3.5 SP1



    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ezhong的博客签名-------------------------------------

    以上内容来自ezhong的博客园,作者:ezhong

    ezhong的博客园: http://www.cnblogs.com/ezhong

    感谢您的阅读。感谢您的分享。

  • 相关阅读:
    Linux简介
    在VMware上安装Ubuntu软件步骤与遇到的相关问题及解决方案
    深度学习框架之TensorFlow的概念及安装(ubuntu下基于pip的安装,IDE为Pycharm)
    Windows下安装Python及Eclipse中配置PyDev插件
    结构体定义struct和typedef struct
    定义与声明
    error LNK2005:错误改正方法
    OPENCV 笔记
    RANSANC算法
    梯度下降法和牛顿法
  • 原文地址:https://www.cnblogs.com/ezhong/p/2321638.html
Copyright © 2011-2022 走看看