栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 内存对齐详解加配图分析

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 内存对齐详解加配图分析

C++内存对齐
因为cpu在存取指令的时候,以字节长为单位进行存取,32位机器默认字节长4字节,64位机器默认长8字节。cpu每次读取都从对齐字节的整数倍开始读取,而存放数据cpu以对齐字节的整数倍进行存放,这要求我们对struct或class内的数据排布提出了要求。

看这样一段代码

#include
using namespace std;
struct A {
    char c;
    short s[3];
    char cs[3];
};
struct B {

    short s[3];
    char cs[3];
    char c;
};
struct C{
    char c;//8   
    double d;//16
    int i[2];//24

};
int main()
{
    A a;
    B b;
    C c;
    printf("%p %p %p %p   %dn", &a,&a.c,a.s,a.cs,sizeof(A));
    //0079FEB0 0079FEB0 0079FEB2 0079FEB8   12
    //            0  ->  2   ->  8  -> 12

    printf("%p %p %p %p    %dn", &b, &b.s, &b.cs, &b.c,sizeof(B));
    //0079FE9C 0079FE9C 0079FEA2 0079FEA5    10
    //            12    ->   16*1+2=18   -> 16*1+5=21   -> 21+1=22   

    printf("%p %p %p %p   %dn", &c, &c.c, &c.d, &c.i, sizeof(C));
    //00F6F81C 00F6F81C 00F6F824 00F6F82C   24
    //            12   ->   16*1+4 = 20  -> 16*1+12=28  ->  28+8=36 
    return 0;
}

struct A的大小占比为12字节

而struct B的大小占10字节

而struct C的大小占8字节?(为啥一个char c需要8字节?==》因为内存对齐是按成员变量中sizeof最大值作为对齐条件)

内存对齐规律

  1. 对于结构体的各个成员,第一个成员位于偏移为0的位置,结构体第一个成员的偏移量(offset)为0,以后每个成员相对于结构体首地址的offset都是该成员大小与有效对齐值中较小那个的整数倍,如有需要编译器会在成员之间加上填充字节。

  2. 除了结构成员需要对齐,结构本身也需要对齐,结构的长度必须是编译器默认的对齐长度和成员中最长类型中最小的数据大小的倍数对齐。

我们再来看看如果struct中有包含sturct呢?

#include
using namespace std;
struct A {
    char c;
    short s[3];
    char cs[3];
};
struct B {

    short s[3];
    char cs[3];
    char c;
};
struct C{
    A a;//12
    char c;//16   
    double d;//24
    int i[2];//32

};
struct D {
    B b;//10
    char c;//16 
    double d;//24
    int i[2];//32

};
int main()
{
    C c;   
    D d;
    printf("%p %p %p %p %p   %dn", &c, &c.a ,&c.c, &c.d, &c.i, sizeof(C));
    //010FFEBC 010FFEBC 010FFEC8 010FFECC 010FFED4   32
    //            12 -> 16+8=24 -> 16+12=28  -> 16*2+4=36 ->  44 
    printf("%p %p %p %p %p   %dn", &d, &d.b, &d.c, &d.d, &d.i, sizeof(D));
    // 010FFE94 010FFE94 010FFE9E 010FFEA4 010FFEAC   32
    //             4   ->     14 ->16+4=20->  16+12=28 -> 36
    //            
    return 0;
}

对于C

对于D

如果把A/B放在C/D的最下面呢?

#include
using namespace std;
struct A {
    char c;
    short s[3];
    char cs[3];
};
struct B {

    short s[3];
    char cs[3];
    char c;
};
struct C{

    char c;//8   
    double d;//8
    int i[2];//8
    A a;//16
};
struct D {

    char c;//8 
    double d;//8
    int i[2];//8
    B b;//16
};
int main()
{
    C c;   
    D d;
    printf("%p %p %p %p %p   %dn", &c ,&c.c, &c.d, &c.i, &c.a, sizeof(C));
    //0113FBFC 0113FBFC 0113FC04 0113FC0C 0113FC14   40
    //            12 -> 16+4=20 -> 16+12=28  -> 16*2+4=36 ->  36+16=52 
    printf("%p %p %p %p %p   %dn", &d, &d.c, &d.d, &d.i, &d.b, sizeof(D));
    // 0113FBCC 0113FBCC 0113FBD4 0113FBDC 0113FBE4   40
    //             12->  16+4=20 ->16+12=28->16*2+4=36->36+16=52
    //            
    return 0;
}

对于C

对于D

所以无论如何它们都要按照8的整数倍进行对齐。

而最后的A/B则因为超过了8所以按16对齐。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/960203.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号