• 内存中的数据对齐


    以下是程序员面试宝典中的一些内容:

        计算结构变量的大小就必须讨论数据对齐问题。为了使CPU存取速度最快(这同CPU去操作数有关,详细的介绍可以参考一些计算机原理方面的书),C++在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,这样做会浪费一些内存,但在理论上CPU速度快了。
        数据对齐,是指数据所在的内存地址必须是该数据长度的整数倍。
        CPU的优化规则大致原则是这样的,对于n字节的元素(n=2,4,8,....),它的首地址能被n整除,才能获得最好的性能。设计编译器的时候可以遵循这个原则:对于每一个变量,可以从当前位置向后找到第一个满足这个条件的地址作为首地址。

    例:以下代码为32位机器编译,数据是以4字节为对齐单位,这两个类的输出结果为什么不同?

    class B
    {
      private:
      bool m_bTemp;
      int  m_nTemp;
          bool m_bTemp2;
    };

    class C
    {
      private:
      int m_nTemp;
      bool m_bTemp;
      bool m_bTemp;
    };

    cout<<sizeof(B)<<endl;
    cout<<sizeof(C)<<endl;
        在访问内存时,如果地址按4字节对齐,则访问效率会高很多。这种现象的原因在于访问内存的硬件电路。一般情况下,地址总线总是按照
    对齐后的地址来访问的。例如你想得到0x00000001开始的4字节内容,系统首先需要以0x00000000读取4字节,从中取得3字节,然后再用  0x00000004作为开始地址,获得下一个4字节,再从中得到第一个字节,两次组合出你想得到的内容。但是如果地址一开始就是对齐到0x00000000,则系统只要一次读写即可。

    本题中,第一种类的数据对齐是下面的情况:
    |bool|----|----|----|
    |--------int--------|
    |bool|----|----|----|
    第二种类的数据对齐是下面的情况:
    |--------int--------|
    |bool|bool|----|----|
    所以类的大小分别是3X4和2X4。       
    答案:B类输出12字节,C类输出8字节。




    struct Node
    {  
          long a1;
          short a2;
    };
    class person
    { private:
          long a1;
          short a2;

    };
    cout << sizeof(long) << endl;//输出为4
    cout << sizeof(int) << endl;//输出为4
    cout << sizeof(short) << endl;//输出为2
    Node t;
    cout << sizeof(t) << endl;//输出为8
    person per;
    cout << sizeof(per) << endl;//输出为8
    在默认情况下,为了方便对结构体内元素的访问和管理,当结构体内的元素的长度都小于处 理器的位数的时候,便以结构体里面最长的数据元素为对齐单元,也就是说,结构体的长度 一定是最长的数据元素的整数倍,如果结构体内存在长度大于处理器位数的元素,那么就以 处理器的位数为对齐单位,但是结构体内类型相同的联素元素将在连续的空间内,和数组一 样

    class A
    {

    };
    class A2
    {
        char d, e;
    };
    cout << sizeof(A) << endl;//输出为1
    cout << sizeof(A2) << endl;//输出为2

    注意:对于一个类而言,即便是它为空类,编译器仍然要给它分配一个空间,即使它什么也
    没有 class A3 {
        static int ch;
    };
    cout << sizeof(A3) << endl;//输出为1
    因为静态变量是存放在全局数据区的,而sizeof计算栈中分配的大小,是不会计算在内的

    class T1
    {

    };
    class T2: public virtual T1
    {

     };
    cout << sizeof(T1) << endl;//输出为1
    cout << sizeof(T2) << endl;//输出为4
    空类所占空间为1,单一继承的空类也为1,多重继承的空类空间还是1,但是虚继承涉及 到虚表(虚指针),所以sizeof(T2)的大小为4
    对于一个空类而言,事实上它有一个隐晦的一字节,那是被编译器安插进去的一个char,这 使得这个class的两个对象得以在内存中配置独一无二的地址

  • 相关阅读:
    【转】sql 如何设计数据库表实现完整的RBAC(基于角色权限控制)
    【转】windows自带终止进程的超强命令
    【源码】 gridview 里使用checkbox
    【转】调用 开始 运行 直接执行命令
    【源码】DropDownList绑定数据
    C++ 编译器数据类型差异
    Flash 中将不透明的 Bitmap 透明化处理
    使用命令行切换IP地址
    MKV 高清视频文件分解与封装和音频编码的转换
    Visual Studio 2010 C++ 用户属性设置
  • 原文地址:https://www.cnblogs.com/fuxianfeng1988/p/3246248.html
Copyright © 2020-2023  润新知