• 结构体内存对齐


        其实这篇文章,原作者是http://www.cnblogs.com/Steak/p/3660403.html

        我之所以再写一遍,是想加一些我自己的理解,以方便日后自己更好理解罢了。

        先看下面的代码:

       

    变量int iTest为4字节,char cTest为1字节,所占用内存应该为5字节。但现在为8字节。那么多出来那3字节就涉及到内存对齐了。我们先看看这个结构体在内在中的分布:

      0 2 3 4 5 6 7 8 9 A B C D E F
    0x10 iTest cTest 空位              
    0x20                              

    由表格中可以看出,iTest占4字节,cTest占1个字节,另外还有3字节的空位。这是因为处理结构体变量时,需要一次读入32位,也就是4个字节。如果没有那3个空位,那么内存就读越界了。那么你可能会说,是哪个混蛋规定处理结构体时,需要一次读4个字节,这不是没事找事做么。那这就要涉及到硬件平台相关和性能问题。平台问题:如果某种CPU只能读4个字节(只是假如...)。性能问题:假如你每次读1个字节,那么读iTest时是不是要读4次呢??当然编译器不一定是这么处理的。但性能的影响大概与之相类似,需要进行更多的运算处理。其实可以设置编译器每次读入的字节数

    #include <iostream>
    using namespace std;
    
    #pragma pack(1)  //1 2 4 6 8 ...决定每次处理结构体变量读入的字节数
    
    typedef struct test
    {
        int iTest;
        char cTest;
    }S_TEST;
    
    int main(int argc,char *argv[])
    {
        cout<<"size:"<<sizeof(S_TEST)<<endl;
    }

    则结果为size:5

    我判断内存对齐的方法:在结构体内,按顺序取变量,每次只读4字节,如果取到了1个以后变量并且把某个变量截断了,就要考虑内存对齐了。

    例1

    struct test
    {
        char a;
        int b;
    }

    按顺序读入4字节,取到了变量a和3/4个变量b,即取到了两个变量并且把b给截断了。所以在截断的地方a和b之间把内存补齐为4。故a后面有3字节的空位。

    例2

    struct test
    {
        double f;
        char a;
        char b;
        char c;
        int d;
        char e;
    }

    按顺序读入4字节,只取到4/8个变量f,再读入4字节,取到一个变量f,没有截断任何变量,不用考虑内存对齐。再读入4字节,取到变量a,b,c,1/4d,c与d之间需要考虑内存对齐。
    再读入4字节,取到d.再读入4字节,取到e还多了,需要考虑内存对齐。

    所以把上面的代码改一下:

    struct test
    {
        double f;
        char a;
        char b;
        char c;
        char e;
        int d;
    }

    则不需要考虑内存对齐。
        事实上,内存对齐对程序员是透明的。即在写程序时,其实我们不用去管这些东西。按我的习惯,把占用内存最小的变量依次声明(先把所有char型变量声明完,再到int,double......),可以避免这些问题。但如果写底层,就要注意这些了。

  • 相关阅读:
    Everybody's business is nobody's business
    Randy Pausch 卡内基梅隆大学毕业典礼上的演讲
    如何写好求职信
    NHibernate中DateTime,int,bool空值的处理方法
    数据库分页存储过程(2)
    数据库分页存储过程(7)
    数据库分页存储过程(3)
    数据库分页存储过程(4)
    给webform中的后置cs文件添加版权
    数据库分页存储过程(5)
  • 原文地址:https://www.cnblogs.com/coding-my-life/p/3661558.html
Copyright © 2020-2023  润新知