结构体成员的内存分配

结构体的内存分配

举个例子就明白了,如下图,似乎除了结构体名没什么区别,内存大小和内存分布也应该没什么区别,
在这里插入图片描述
但是实际上:

 sizeof(A) = 9
 sizeof(B) = 16

导致这一差异的就是内存对齐,为什么有内存对齐,以及什么是内存对齐在这就不阐述了,可以自行度娘,反正目的是为了加快性能, 内存对齐的规则如下,也是编译器给结构体开辟内存时遵循的规则:

1、第一个成员的相对于结构体首地址的偏移(offset)为0.
2、每个成员的相对于首地址的偏移(offset)为:对齐值与成员类型长度的较小值的整数倍
3、没有指定对齐值的情况下,默认对齐值为结构体成员类型最长的值作为对齐值
4、结构体的总大小,为对齐值的整数倍。

这个规则就确认了结构体成员的内存分布及内存大小,上图中,结构体A指定了内存对齐为1字节对齐,那么按照规则A中各成员分布如下图:
在这里插入图片描述
B为默认对齐,显然,对齐值为类型int的长度,假设为4,内存分配如下图:
在这里插入图片描述

为什么会如此分布?我们尝试给每个成员分配内存

  • c1: 分配内存为1字节,占据索引为“0”的位置
  • i: 分配4个字节长度,但是按照规则2,距首地址要有4的整数倍偏移,所以i为起始位置为“4”,长度为4
  • c2: 分配1字节,占据索引为“8”的位置 s2: 分配2字节,依照规则2,偏移为2个倍数,起始为“10”,长度为2
  • c3:分配1个字节,占据索引为“12”的位置,按照规则4,总长度需要是4的倍数,因此还需要额外补充3个字节

因此B的总长度16,其中有部分内存是未使用的,可以说是浪费的,但是合理的
以下是一段测试验证代码:


#include <iostream>
#include <new>
#include <cstdio>
using namespace std;

#pragma pack(1)
struct A
{
public:
    char c1;
    int i;
    char c2;
    short s1;
    char c3;
};
#pragma pack()

struct B
{
    char c1;
    int i;
    char c2;
    short s1;
    char c3;
};
void printA(A a){

    cout<<"A:"<<a.c1<<","<<a.i<<","<<a.c2<<","<<a.s1<<","<<a.c2<<","<<a.c3<<endl;
    int h1 = 0x000000ff & a.i;
    int h2 = 0x000000ff & (a.i >>8);
    int h3 = 0x000000ff & (a.i >>16);
    int h4 = 0x000000ff & (a.i >>24);
    cout<<"h1:"<<h1<<" h2:"<<h2<<" h3:"<<h3<<"  h4:"<<h4<<endl;

}

void printB(B a){

    cout<<"B:"<<a.c1<<","<<a.i<<","<<a.c2<<","<<a.s1<<","<<a.c2<<","<<a.c3<<endl;
    int h1 = 0x000000ff & a.i;
    int h2 = 0x000000ff & (a.i >>8);
    int h3 = 0x000000ff & (a.i >>16);
    int h4 = 0x000000ff & (a.i >>24);
    cout<<"h1:"<<h1<<" h2:"<<h2<<" h3:"<<h3<<"  h4:"<<h4<<endl;

}

int main(int argc, char *argv[])
{

    cout<<"sizeof(A)"<<sizeof(A)<<endl;
    cout<<"sizeof(B)"<<sizeof(B)<<endl;

    //26个字母的字符
    char buff[26] = {0};
    for(int i=0;i<26;i++)
        buff[i] = 97+i;//字符 a 的值为97

    A a = {0};
    memcpy(&a,buff,sizeof(A));
    printA(a);
    B b = {0};
    memcpy(&b,buff,sizeof(B));
    printB(b);


}

程序打印
在这里插入图片描述
打印结果和理论上是一致的(下图的内存分布)
在这里插入图片描述

假设结构体重包含结构体内存怎么分配?依然按照原则分配就是,值得一提的是,内存对齐值不是结构体的长度,而是结构体内部成员类型长度最大的值,你可以理解为对齐值对比的是基础类型的内存长度(char,short,int,long,double,float等),下图中内存对齐值不是sizeof(B),而是结构体B中的类型int的所占内存的长度值。
那么这里的B的起始位置为什么在“105”而不是在“102”?
依然对比规则,规则2规定了,每个成员的偏移量为内存对齐值的整数倍,结构体B才是是D的成员,所以B的起始位置距离D结构体的起始位置要是4的倍数,因此B的起始位置在“105”
在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dai1396734

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值