精华内容
下载资源
问答
  • 内存对齐方式

    2017-09-02 12:19:00
    一般我们编程的时候short s=2,int i=4,char c=’a’在内存中是如何...因为这是内存对齐的一种方式,在32位系统中默认为4字节对齐。 (2)为啥使用4字节对齐? 因为32位系统CPU一次读取内存为32位,4字节(64位系统

    一般我们编程的时候short s=2,int i=4,char c=’a’在内存中是如何对齐的呢?
    在32位系统中:
    这里写图片描述
    在64位系统中:
    这里写图片描述
    (1)以32位系统为例,short后面还有两个字节,为啥char c=’a’没有放到那个位置?
    因为这是内存对齐的一种方式,在32位系统中默认为4字节对齐。
    (2)为啥使用4字节对齐?
    因为32位系统CPU一次读取内存为32位,4字节(64位系统一次读8个字节),如果要读8字节,则CPU要读两次内存,如果要读2字节,CPU首先先读出4字节,然后再截取2字节,所以这样的对齐方式,虽然浪费内存,但是有利于提高从内存读取数据的速度。
    (3)是否可以更改内存的对齐方式?
    可以,在C语言中可以使用#pragma pack (*) 等更改内存对齐方式。

    展开全文
  • c++内存对齐方式

    2019-07-18 09:28:46
    一,什么是内存对齐内存对齐用来做什么? 所谓内存对齐,是为了让内存存取更有效率而采用的一种编译阶段优化内存存取的手段。 比如对于int x;(这里假设sizeof(int)==4),因为cpu对内存的读取操作是对齐的,如果...

    转自:https://www.cnblogs.com/xylc/p/3780907.html(博客园)

    一,什么是内存对齐?内存对齐用来做什么?

    所谓内存对齐,是为了让内存存取更有效率而采用的一种编译阶段优化内存存取的手段。

    比如对于int x;(这里假设sizeof(int)==4),因为cpu对内存的读取操作是对齐的,如果x的地址不是4的倍数,那么读取这个x,需要读取两次共8个字节,然后还要将其拼接成一个int,这比存取对齐过的x要麻烦很多。

    二,怎么算内存对齐大小(理论)?

    对于简单类型,如int,char,float等,其对齐大小为其本身大小,即align(int) == sizeof(int),align(char)==sizeof(char),等等。

    对于复合类型,如struct,class,其本身并无所谓对齐,因为CPU没有直接存取一个struct的指令。对于struct而言,它的对齐指的是它里面的所有成员变量都是对齐的,class同理。

    下面就讲讲struct对齐是怎么回事。

    首先要明白三个点:

    1,内存对齐是指首地址对齐,而不是说每个变量大小对齐;

    2,结构体内存对齐要求结构体内每一个成员变量都是内存对齐的;

    3,结构体对齐除了第2点之外还要求结构体数组也必须是对齐的,也就是说每个相邻的结构体内部都是对齐的。

    OK,先知道上面这3点之后,开始接触怎么算对齐大小。

    程序员可自己指定某些数据的对齐大小,通过使用下面的预处理指令,指定对齐大小为x。(这里需要注意:只能指定2的n次方作为对齐大小,对于指定对齐大小为6,9,10这样的编译器可能会不予理会)。

    #pragma pack(x)
    //...
    #pragma pack()
    

    那到现在,可能大家有个疑问了,那对于int(这里假设sizeof(int)==4),手动指定对齐大小为8,那align(int)是等于sizeof(int)还是等于8呢 ?

    这里大家可以记住,align(x) = min ( sizeof(x) , packalign) , 即sizeof(x)和指定对齐大小哪个小,对齐大小就为哪个。

    因此,上面的疑问答案是align(int)=sizeof(int)=4 。

    三,怎么算内存对齐大小(示范)?

    #include <cassert>
    
    
    int main(int argc, char* argv[])
    {
        //此处指定对齐大小为1
        //对于a,实际对齐大小为min(sizeof(int),1)=min(4,1)=1
        //对于b,实际对齐大小为min(sizeof(char),1)=min(1,1)=1
        //编译器会确保TEST_A首地址即a的地首址是1字节对齐的,此时a对齐
        //对于b,由于b要求首地址1字节对齐,这显然对于任何地址都合适,所以a,b都是对齐的
        //对于TEST_A数组,第一个TEST_A是对齐的(假设其地址为0),则第二个TEST_A的首地址为(0+5=5),对于第二个TEST_A的两个变量a,b均对齐
        //OK,对齐合理。因此整个结构体的大小为5
    #pragma pack(1)
        struct TEST_A
        {
            int a;
            char b;
        };
    #pragma  pack()
        assert(sizeof(TEST_A) == 5);
    
        //此处指定对齐大小为2
        //对于a,实际对齐大小为min(sizeof(int),2)=min(4,2)=2
        //对于b,实际对齐大小为min(sizeof(char),2)=min(1,2)=1
        //编译器会确保TEST_A首地址即a的地首址是2字节对齐的,此时a对齐
        //对于b,由于b要求首地址1字节对齐,这显然对于任何地址都合适,所以a,b都是对齐的
        //对于TEST_B数组,第一个TEST_B是对齐的(假设其地址为0),则第二个TEST_B的首地址为(0+5=5),对于第二个TEST_B的变量a,显然地址5是不对齐于2字节的
        //因此,需要在TEST_B的变量b后面填充1字节,此时连续相连的TEST_B数组才会对齐
        //OK,对齐合理。因此整个结构体的大小为5+1=6
    #pragma pack(2)
        struct TEST_B
        {
            int a;
            char b;
        };
    #pragma  pack()
        assert(sizeof(TEST_B) == 6);
    
        //此处指定对齐大小为4
        //对于a,实际对齐大小为min(sizeof(int),2)=min(4,4)=4
        //对于b,实际对齐大小为min(sizeof(char),2)=min(1,4)=1
        //编译器会确保TEST_A首地址即a的地首址是4字节对齐的,此时a对齐
        //对于b,由于b要求首地址1字节对齐,这显然对于任何地址都合适,所以a,b都是对齐的
        //对于TEST_C数组,第一个TEST_C是对齐的(假设其地址为0),则第二个TEST_C的首地址为(0+5=5),对于第二个TEST_C的变量a,显然地址5是不对齐于4字节的
        //因此,需要在TEST_C的变量b后面填充3字节,此时连续相连的TEST_C数组才会对齐
        //OK,对齐合理。因此整个结构体的大小为5+3=8
    #pragma pack(4)
        struct TEST_C
        {
            int a;
            char b;
        };
    #pragma  pack()
        assert(sizeof(TEST_C) == 8);
    
        //此处指定对齐大小为8
        //对于a,实际对齐大小为min(sizeof(int),8)=min(4,8)=4
        //对于b,实际对齐大小为min(sizeof(char),8)=min(1,8)=1
        //编译器会确保TEST_A首地址即a的地首址是4字节对齐的,此时a对齐
        //对于b,由于b要求首地址1字节对齐,这显然对于任何地址都合适,所以a,b都是对齐的
        //对于TEST_D数组,第一个TEST_D是对齐的(假设其地址为0),则第二个TEST_D的首地址为(0+5=5),对于第二个TEST_D的变量a,显然地址5是不对齐于4字节的
        //因此,需要在TEST_D的变量b后面填充3字节,此时连续相连的TEST_D数组才会对齐
        //OK,对齐合理。因此整个结构体的大小为5+3=8
    #pragma pack(8)
        struct TEST_D
        {
            int a;
            char b;
        };
    #pragma  pack()
        assert(sizeof(TEST_D) == 8);
    
    
        //此处指定对齐大小为8
        //对于a,实际对齐大小为min(sizeof(int),8)=min(4,8)=4
        //对于b,实际对齐大小为min(sizeof(char),8)=min(1,8)=1
        //对于c,这是一个数组,数组的对齐大小与其单元一致,因而align(c)=align(double)=min(sizeof(double),8)=min(8,8)=8
        //对于d,实际对齐大小为min(sizeof(char),8)=min(1,8)=1
        //编译器会确保TEST_A首地址即a的地首址是4字节对齐的,此时a对齐
        //对于b,由于b要求首地址1字节对齐,这显然对于任何地址都合适,所以a,b都是对齐的
        //对于c,由于c要求首地址8字节对齐,因此前面的a+b=5,还要在c后面补上3个字节才能对齐
        //对于d,显而易见,任何地址均对齐,此时结构体大小为4+1+3+10*8+1=89
        //对于TEST_E数组,第一个TEST_E是对齐的(假设其地址为0),则第二个TEST_E的首地址为(0+89=89),对于第二个TEST_E的变量a,显然地址89是不对齐于4字节的
        //因此,需要在TEST_E的变量d后面填充7字节,此时连续相连的TEST_E数组才会对齐 
        //(注意:此处不仅要确保下一个TEST_E的a,b变量对齐,还要确保c也对齐,所以这里不是填充3字节,而是填充7字节)
        //OK,对齐合理。因此整个结构体的大小为(4)+(1+3)+(10*8)+(1+7)=96
    #pragma pack(8)
        struct TEST_E
        {
            int a;
            char b;
            double c[10];
            char d;
        };
    #pragma  pack()
        assert(sizeof(TEST_E) == 96);
    
        return 0;
    }
    

    四,内存对齐相关

    使用msvc未公开编译选项可以查看c++类的内存布局。使用方法:启动vs命令行,输入cl 【source.cpp】 /d1reportSingleClassLayout【CBaseClass1】以查看单个class的内存布局,输入cl 【source.cpp】 /d1reportAllClassLayout以查看所有类的内存布局。注意:/d1reportSingleClassLayout【CBaseClass1】没有空格 !!

    大家可以用这个来对照我上面讲的例子来看编译器是怎么安排对齐的。

    这个东东是神器,类似于宏展开时的选项(输出与处理过之后的源文件),一切内部布局方面的真相全都展现在你眼前,包括坑脑细胞的虚函数、虚函数表、虚基类表、虚继承等一系列坑爹。

    五,参考资料

    1,http://blog.csdn.net/arethe/article/details/2548867

    2,http://msdn.microsoft.com/en-us/library/83ythb65.aspx

    3,http://msdn.microsoft.com/en-us/library/9dbwhz68.aspx

    4,http://msdn.microsoft.com/en-us/library/71kf49f1.aspx

    5,http://blog.sina.com.cn/s/blog_67c294ca01012qbu.html

    展开全文
  • 1. 内存对齐方式虽然所有的变量最后都会保存在特定地址的内存中,但相应的内存空间必须满足内存对齐的要求。主要出于两个方面的原因: (1) 平台原因: 不是所有的硬件平台(特别是嵌入式系统中使用的低端处理器)...

    1. 内存对齐方式

    虽然所有的变量最后都会保存在特定地址的内存中,但相应的内存空间必须满足内存对齐的要求。主要出于两个方面的原因:
    (1) 平台原因:
    不是所有的硬件平台(特别是嵌入式系统中使用的低端处理器)都能访问任意地址上的任意数据,某些硬件平台只能访问对齐的地址,否则会出现硬件异常。
    (2) 性能原因:
    如果数据存放在未对齐的内存空间中,则处理器访问变量时需要做两次内存访问,而对齐的内存访问仅需一次访问。

    在32位微处理器中,处理器访问内存都是按照32位进行的,即一次读取或写入都是4个字节,比如地址0x0~0xF这16字节的内存,对于微处理器来说,不是将其看做16个单一字节,而是4个块,每块4个字节。如下图
    这里写图片描述

    显然,只能从0x0、0x4、0x8、0xC等地址为4的整数倍的内存中一次取出4个字节,并不能从任意地址开始一次读取4个字节。假定将一个占用4个字节的int类型的数据存放在地址0开始的4字节内存中,其示意图如下
    这里写图片描述
    由于int类型数据存放在块0中,因此CPU仅需一次内存访问即可完成对该数据的读取或写入。反之,如果将int类型数据存放在地址1开始的4字节内存空间中,其示意图如下
    这里写图片描述
    此时,数据存放在块0和块1两个块中,若要完成对该数据的访问,必须经过两次内存访问,先访问块0得到数据的3个字节,再通过访问块1得到该数据的1个字节,最后通过运算,将这几个字节合并为一个完整的int型数据。由此可见,若数据存储在未对齐的内存空间中,将大大降低CPU的效率。但在某些特定的微处理器中,它根本不愿意干这种事情,这种情况下,就出现系统异常,直接崩溃了。

    2. 结构体的存储

    我们知道,数组是相同类型有序数据的集合,但很多时候需要将不同类型的数据捆绑在一起作为一个整体对待,使程序设计更方便。在C语言中,这样一组数据被称为结构体。其内存对齐的规则如下:
    (1) 结构体各个成员变量的内存空间的首地址必须是“对齐系数”和“变量实际长度”中较小者的整数倍。“对齐系数”是【#pragma pack指定的数值】、【未指定#pragma pack时,系统默认的对齐模数(32位系统为4字节,64位为8字节)】。假设要求变量的内存空间要求按照4字节对齐,则内存空间的首地址必须是4的整数倍,满足条件的地址为0x0, 0x4, 0x8, 0xC…
    (2) 对于结构体,在其各个数据成员都完成对齐后,结构体本身也需要对齐,即结构体占用的总大小应该为“对齐系数”和“最大数据成员长度”中较小值的整数倍。

    如下的结构体,在32位机器上编译,其成员数据的总长度为4+2+3+4+1+8 = 22(字节)

    #pragma pack(4)
    struct TEST
    {
        long a;         //4
        short b;        //2
        char c[3];      //3
        float d;        //4
        char e;         //1
        double f;       //8
    }test;
    

    有如下的测试程序

    int main(void)
    {
        short len = sizeof(test);
        printf("test length is %d.\n", len);
        return 0;
    }

    下面是输出结果,结果表明结构体占用28个字节的内存,大于22字节。
    这里写图片描述
    其实,正是由于内存对齐的原因造成了这种现象,下图是每个变量在内存的分布图,其中空白部分是内存弃用部分,这些浪费空间的前面,存放的都是char型数据,由于char型数据只占用一个字节,往往使得其紧接着的空间不能被其它长度更长的数据使用。
    这里写图片描述

    为了降低内存浪费的概率,应该在char型数据之后,存放长度较小的成员。即在定义结构体时,应该按照长度递增的顺序依次定义各个成员。优化后的实例代码为

    #pragma pack(4)
    struct TEST
    {
        char e;         //1
        char c[3];      //3
        short b;        //2
        long a;         //4
        float d;        //4
        double f;       //8
    }test;

    运行测试程序,输出结果为
    这里写图片描述
    可见,通过调整结构体的成员顺序,达到了优化内存的目的。各个成员变量在内存中的分布图为
    这里写图片描述

    结构体只浪费了2个字节的空间,内存使用率达到92%。显然通过优化结构体成员的定义顺序,在同样满足内存对齐的要求下,可以大大减小内存的浪费。

    展开全文
  • Golang内存对齐方式

    2021-01-18 10:52:00
    Go语言是如何进行内存对齐的? type T struct { a bool b int8 c uint16 d uint32 e int64 f bool} 类型尺寸 go白皮书只对以下类型占用的内存大小进行了明确规定. uint和int类型的大小取决于编译器和...

    Go语言是如何进行内存对齐的?

     

    type T struct {
        a
    bool
        b int8
        c uint16
        d uint32
        e int64
        f bool
    }

     

    类型尺寸

    go白皮书只对以下类型占用的内存大小进行了明确规定.

     

    uint和int类型的大小取决于编译器和系统架构,通常32位架构为4字节,64位架构为8字节

    uintptr 取决于编译器实现,但必须保证一定能够存下任一个内存地址.

    除了上述明确规定的,白皮书没有对其他种类的类型尺寸进行明确规定.

    类型尺寸获取代码:

    func main() {

            var i bool = true

            var j int = 40

            fmt.Println("bool-size", unsafe.Sizeof(i))

            fmt.Println("int-size", unsafe.Sizeof(j))

    }

    输出结果:

    bool-size 1

    int-size 8

    bool类型的大小占用1字节

    int类型的大小占用8字节,因为我是64位系统,如果你是32位的输出会是4

    如果仅仅按照类型尺寸的规则,来累加计算结构体T中每个字段的存储大小,发现和实际存储的大小不一样的.因为Go在分配结构体内存的时候,还需要参照对齐保证。

    对齐保证:

    对齐保证也称为值地址对齐保证,也就是在分配变量存储位置的时候,不是随便分配的,是按照对齐保证整数倍来分配内存地址的。

    1. 对于任何类型的变量x,unsafe.Alignof(x)最小为1

    2. 对于结构体类型变量x,unsafe.Alignof(x)的数值是结构体中所有字段的对齐保证中的最大值( the largest ),作为结构体的对齐保证,最小为1.

    3. 对于数组类型变量x, unsafe.Alignof(x)的结果和数组元素的类型的对齐保证一致.

     

    Go只是规定了对齐保证的基本规则,但是对于不同编译器不同的架构甚至于同一个编译器的不同版本,实现的对齐保证都会有一定的差异,了解规则即可.

    每个类型有两个对齐保证。

    • 当它被用作结构体类型的字段的字段类型时的对齐保证称为此类型的字段对齐保证
    • 其他情形的对齐保证称为此类型的一般对齐保证。

     

    func main() {

            var i bool = true

            var j int = 40

            fmt.Println("bool-size", unsafe.Alignof(i)) //一般对齐保证

            fmt.Println("int-size", unsafe.Alignof(j))

            type temp struct {

                    a bool

                    b int

            }

            var tmp = temp{}

            fmt.Println("a", unsafe.Alignof(tmp.a)) //字段对齐保证

            fmt.Println("b", unsafe.Alignof(tmp.b))

    }

     

    输出结果:

    bool-size 1

    int-size 8

    a 1

    b 8

    实例应用:

    内存对齐遵循的规则

    变量的存储起始地址一定是对齐保证的整数倍

    变量的大小是对齐保证的整数倍,所有的类型都要遵守一规则。

    type T struct {

            a bool

            b int8

            c uint16

            d uint32

            e int64

            f bool

    }

     

    func main() {

            var t = T{}

            fmt.Println("t占用的实际内存大小:", unsafe.Sizeof(t), "字节,结构体对齐保证:", unsafe.Alignof(t))

            fmt.Println("a:", unsafe.Sizeof(t.a), "字节,字段对齐保证:", unsafe.Alignof(t.a), ",偏移地址:", unsafe.Offsetof(t.a))

            fmt.Println("b:", unsafe.Sizeof(t.b), "字节,字段对齐保证:", unsafe.Alignof(t.b), ",偏移地址:", unsafe.Offsetof(t.b))

            fmt.Println("c:", unsafe.Sizeof(t.c), "字节,字段对齐保证:", unsafe.Alignof(t.c), ",偏移地址:", unsafe.Offsetof(t.c))

            fmt.Println("d:", unsafe.Sizeof(t.d), "字节,字段对齐保证:", unsafe.Alignof(t.d), ",偏移地址:", unsafe.Offsetof(t.d))

            fmt.Println("e:", unsafe.Sizeof(t.e), "字节,字段对齐保证:", unsafe.Alignof(t.e), ",偏移地址:", unsafe.Offsetof(t.e))

            fmt.Println("f:", unsafe.Sizeof(t.f), "字节,字段对齐保证:", unsafe.Alignof(t.f), ",偏移地址:", unsafe.Offsetof(t.f))

            fmt.Println(uintptr(unsafe.Pointer(&t)))

    }

    输出结果:

    t占用的实际内存大小: 24 字节,结构体对齐保证: 8

    a: 1 字节,字段对齐保证: 1 ,偏移地址: 0

    b: 1 字节,字段对齐保证: 1 ,偏移地址: 1

    c: 2 字节,字段对齐保证: 2 ,偏移地址: 2

    d: 4 字节,字段对齐保证: 4 ,偏移地址: 4

    e: 8 字节,字段对齐保证: 8 ,偏移地址: 8

    f: 1 字节,字段对齐保证: 1 ,偏移地址: 16

    824634834128

    如果按照上面输出的字段大小累加(1+1+2+4+8+1 = 17字节)明显和实际内存大小24字节不符合.现在来一步步解析上面的结果是怎么出来的.

    以此类推

     

     

    最后一个变量f完美分配完成,但是这个时候整个结构体类型还需要满足一个条件,类型的大小需要是对齐保证的整数倍.

    结构体的对齐保证是所有字段对齐保证中的最大值,这里为8.而分配的内存大小只有17字节,不满足整数倍的关系.需要填充7字节,保证这个关系

    最终结构体t的内存分配完成为24字节,符合我们的打印输出

    结构体在内存中完整的存储图示:

     

     

     

    举一反三:这里把结构体T中c和d字段的位置替换下,定义结构体R,再来验证下上面分析规则.

     

    输出结果:

    package main

     

    import (

            "fmt"

            "unsafe"

    )

     

    type R struct {

            a bool

            b int8

            d uint32

            c uint16

            e int64

            f bool

    }

     

    func main() {

            var r = R{}

            fmt.Println("r占用的实际内存大小:", unsafe.Sizeof(r), "字节,结构体对齐保证:", unsafe.Alignof(r))

            fmt.Println("a:", unsafe.Sizeof(r.a), "字节,字段对齐保证:", unsafe.Alignof(r.a), ",偏移地址:", unsafe.Offsetof(r.a))

            fmt.Println("b:", unsafe.Sizeof(r.b), "字节,字段对齐保证:", unsafe.Alignof(r.b), ",偏移地址:", unsafe.Offsetof(r.b))

            fmt.Println("d:", unsafe.Sizeof(r.d), "字节,字段对齐保证:", unsafe.Alignof(r.d), ",偏移地址:", unsafe.Offsetof(r.d))

            fmt.Println("c:", unsafe.Sizeof(r.c), "字节,字段对齐保证:", unsafe.Alignof(r.c), ",偏移地址:", unsafe.Offsetof(r.c))

            fmt.Println("e:", unsafe.Sizeof(r.e), "字节,字段对齐保证:", unsafe.Alignof(r.e), ",偏移地址:", unsafe.Offsetof(r.e))

            fmt.Println("f:", unsafe.Sizeof(r.f), "字节,字段对齐保证:", unsafe.Alignof(r.f), ",偏移地址:", unsafe.Offsetof(r.f))

            fmt.Println(uintptr(unsafe.Pointer(&r)))

    }

    输出结果:

    r占用的实际内存大小: 32 字节,结构体对齐保证: 8

    a: 1 字节,字段对齐保证: 1 ,偏移地址: 0

    b: 1 字节,字段对齐保证: 1 ,偏移地址: 1

    d: 4 字节,字段对齐保证: 4 ,偏移地址: 4

    c: 2 字节,字段对齐保证: 2 ,偏移地址: 8

    e: 8 字节,字段对齐保证: 8 ,偏移地址: 16

    f: 1 字节,字段对齐保证: 1 ,偏移地址: 24

    824634834120

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 2015年10月12日 01:19:24 Cainv89 阅读数:12402 标签: 结构体复合数据类型C与C++结构体区别结构体的作用结构体的内存对齐方式 更多 个人分类: C++基础 版权声明:本文为博主原创文章,未经博主允许不得...
  • 结构体的对齐方式必须是程序员所了解的,关于内存对齐方式的优点和部分知识可以参阅http://www.ibm.com/developerworks/library/pa-dalign/ 结构体占用的存储空间(struct & sizeof) 概要:结构体所占用的空间只...
  • C++内存对齐方式

    2015-01-30 12:42:00
    一、什么是内存对齐、为什么需要内存对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问...
  • C语言中内存对齐方式

    2015-04-16 22:08:58
    内存对齐,因为它是对C/C++程序员透明的,在很多C,C++课本中也没有讲清楚,所以今天写了这篇博客,讲述为什么需要内存对齐内存对齐怎么计算·····
  • Struct 和 Union区别 以及 对内存对齐方式的说明 转载地址:http://blog.csdn.net/firefly_2002/article/details/7954458 一、Struct 和 Union有下列区别: 1.在存储多个成员信息时,编译器会自动给struct第个...
  • C、C++中的内存对齐方式/
  • 问题解答https://www.cnblogs.com/jijiji/p/4854581.html
  • 结构体内存对齐方式

    2018-07-09 21:29:51
    c、按a、b、两步骤算出结构体实际所占内存时,为了方便后面类型的存储,再向后偏移一位,然后判断该地址是否是默认对齐数与该结构体中最大类型所占字节数的最小值 ,即:min(默认对齐参数,类型最大字节数)的整数倍...
  • 数据对齐,是指数据所在的内存地址必须是该数据长度的整数倍。DWORD数据的内存起始地址能被4除尽,WORD数 据的内存起始地址能被2除尽。x86 CPU能直接访问对齐的数据,当它试图访问一个未对齐的数据时,会在内部进行...
  • struct的内存对齐方式

    2015-10-25 13:46:23
    struct的内存对齐规则: 一、在没有pack声明的情况下: 1.计算时假设第一个元素存储的位首地址为0,之后每个元素存储的首地址都是该元素的大小的整数倍开始,比如 Struct a{ char a1; int a2; } 其中...
  • 原来对内存对齐一直没弄清楚,现在找到两篇网友的文章备忘: http://blog.csdn.net/arethe/article/details/2548867 http://blog.sina.com.cn/s/blog_59b189220100a49h.html 一、什么是对齐,以及为什么...
  • C/C++中内存对齐方式

    2016-10-25 22:45:05
    我们平时在学习中或是在做一些面试题的过程中,可能会经常碰到让你填写一个数据结构或者一个类的大小的题目,那么这种类型的题目就涉及到了内存对齐问题,下面就详细的给大家介绍一下。 一. 什么是对其方式,以及...
  • 一.背景:1.使用#pragma定义结构体:RECV_CMD_DATA_t和RECV_CMD_PACK_t,按照1字节进行内存对齐#pragma pack(1) typedef struct recv_cmd_data { int iType; long long llInt; int iLen; ...
  • 具体的理论内容 神马是内存对齐以及为何要内存对齐请看http://blog.csdn.net/kokodudu/article/details/11918219 上面这个连接 将的相当理论 我给简化了一下 但是还是必须要看的 这里对如何计算结构体所占内存大小...
  • #pragma pack 设置内存对齐方式

    千次阅读 2012-10-31 08:20:19
    为了提高CPU的存储效率,编译器往往对class 和 struct ...来设置成 n字节的对齐方式   类中的static变量不会给类带来空间负担,也就是不被计算到类的大小中。   #include using namespace std; #pragma pack(4
  • 内存对齐方式的探究

    2011-08-02 21:29:24
    什么是对齐,以及为什么要对齐: 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型...
  • 自定义内存对齐方式

    2011-03-21 21:43:00
    编译器中,我们可以指定其对齐方式 ,其操作方式为依次选择 projetct > setting > C/C++ 菜单,在 struct member alignment 中指定你要的对其方式。  5. 使用packed,仅在你需要的时候。
  • 【1】内存对齐方式 C++代码: #pragma pack(push) #pragma pack(1) typedef struct _testStru2 { int iVal; char cVal; __int64 llVal; }testStru2; #pragma pack(pop) EXPORTDLL_API void Struct_...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,431
精华内容 572
关键字:

内存对齐方式