zoukankan      html  css  js  c++  java
  • 内存对齐

    内存对齐由编译器负责,编译器为程序中的每个"数据单元"安排在适当的位置上。

    内存对齐原因:

       (1)平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

      (2)性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

    内存对齐规则:

      每个特定平台上的编译器都有自己的默认"对齐系数"(也叫对齐模数)。32位编译器默认4字节,64位编译器默认8字节。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的"对齐系数"。

    1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。

    2、结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。

    3、结合1、2可推断:当#pragma pack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果。

    内存的自然对齐:每一种数据类型都必须放在地址中的整数倍上 

    例如:

    地址4可以放char(1)类型,可以放int(4)型,可以放short(2)型,但是不能存放double(8)型,仅仅因为4不是8的整数倍。 
    地址3能存放char型,但是其他int,short,double都不能存放。 
    有一个特殊地址,就是0,它可以是任何类型的整数倍,所以可以存放任何数据。 

    结构体内存分配原则:

    1.结构体的总大小,必须要是其内部最大成员的整数倍。

    2..结构体或union联合的数据成员,第一个数据成员是要放在offset == 0的地方,如果遇上子成员,要根据子成员的类型存放在对应的整数倍的地址上 
    3..如果结构体作为成员,则要找到这个结构体中的最大元素,然后从这个最大成员的整数倍地址开始存储(strutc a中有一个struct b,b里面有char,int,double….那b应该从8的整数倍开始存储)

    4. 结构体或类的静态成员变量不计算在内存对齐中, sizeof只计算栈内分配内存

    例如

    class Base{
        int a;
        static double b;
        char c;
    };
    double Base::b = 0;
    cout << sizeof(Base); // 值为8
  • 相关阅读:
    Java—CountDownLatch使用详解
    Java—线程的生命周期及线程控制方法详解
    Java反射机制详解
    一点点点点点算法刷题总结
    Java并发编程:线程池ThreadPoolExecutor
    Java并发编程:线程和锁的使用与解析
    MySQL——关于索引的总结
    常用设计模式的实现,以及Netty中的设计模式
    Netty入门与实战教程
    手动搭建I/O网络通信框架4:AIO编程模型,聊天室终极改造
  • 原文地址:https://www.cnblogs.com/dj0325/p/8491385.html
Copyright © 2011-2022 走看看