C++中为什么变量的声明顺序不同所占用的总内存就不同

像inta;boolb;boolc;与boola;intb;boolc;这两种声明顺序所占的总内存为什么不同(前者8B,后者12B)?望高手赐教... 像int a;bool b;bool c;与 bool a;int b;bool c; 这两种声明顺序所占的总内存为什么不同(前者8B,后者12B)?望高手赐教 展开
 我来答
liugang585570
2010-03-08 · 超过22用户采纳过TA的回答
知道答主
回答量:76
采纳率:0%
帮助的人:39.5万
展开全部
在编译过程中c++编译器为了提高存取速度,设置了在存储格式上的字节对齐。

------------------------------------------------
1.为什么设置字节对齐能提高存取速度
------------------------------------------------
答:主要是因为现代计算机都使用了Cache。
Cache可以看成一些可以用非常快的速度进行访问的临时内存。但是Cache的容量不大,比如一般一级Cache只有几K到几十K,二级Cache只有几百K到几M.这个同数G的内存相比,是比较小的。
但是CPU访问内存非常慢,所以硬件会将平时经常使用的内容存放到Cache里面。Cache是通过一些Cache Line来组织的,每一条Cache Line一般包含16个字节,32个字节或64个字节等。 比如某个计算机一级Cache的Cache Line长度是32个字节,那么每段Cache Line总是会包含32个字节对齐的一段内存。
现在有一个4字节的整数,如果它的地址不是4字节对齐的,那么就有可能访问它的时候,需要使用两条Cache Line,这增加了总线通讯量,而且增加了对Cache的使用量,而且使用的数据没有在Cache里面(这时需要将数据从内存调入Cache,会非常慢)的机会会增加,这些都降低了程序的速度。

------------------------------------------------
2.字节对齐过程分析
------------------------------------------------
答:在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。下面列出常用类型的对齐方式(vc6.0 32位系统)
类型 对齐方式(变量存放的起始地址相对于结构的其实地址的偏移量)
char 偏移量必须为sizeof(char)即1的倍数
int 偏移量必须为sizeof(int)即4的倍数
float 偏移量必须为sizeof(float)即4的倍数
double 偏移量必须为sizeof(double)即8的倍数
short 偏移量必须为sizeof(short)即2的倍数

各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节vc会自动填充。同时vc为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。
以你的情况为例:
struct Mystruct1
{
int a;
bool b;
bool c;
}
为上面的结构分配空间的时候,vc根据成员变量出现的顺序和对齐方式,先为第一个成员a分配空间,其起始地址跟结构的起始地址相同(偏移量为0,刚好为sizeof(int)的倍数),该成员变量占用sizeof(int)=4个字节;接下来为第二个成员b分配空间,这时下一个可以分配的地址相对于结构的起始地址的偏移量为4,是size(bool)=1的倍数(注意:sizeof(BOOL)=4;sizeof(bool)=1),所以把b存在在偏移量为4的地方满足对齐方式,该成员变量占用1个字节;接下来为第三个成员c分配空间,这时下一个可以分配的地址相对于结构的其实地址的偏移量为5,是sizeof(bool)的倍数,所以c存放在偏移量为5的地方满足对齐方式。
这时,所有的成员变量都分配的空间,总空间的大小为4+1+1=6,不是结构的字节边界数(即结构中占用最大空间的类型所占用的字节sizeof(int)=4)的倍数,所以需要填充2个字节,以满足结构的大小为sizeof(int)=4的倍数。这时结构占用的内存大小为4+1+1+2=8。

同样的道理
struct Mystruct1
{
bool a;
int b;
bool c;
}
的分配方式为:
第一个成员变量a占用1个字节,相对于结构的起始地址偏移量为0,满足对齐方式;第二个成员变量b占用4个字节,下一个可用的地址的偏移量为1,不是4的倍数,需要补足3个字节才能使偏移量为4(满足对齐方式),因此vc自动填充3个字节,b存放在偏移量为4的地址上,它占用4个字节。第三个成员变量c占用1个字节,下一个可用的地址为8(满足对齐方式),所以存放在偏移量为8的地址上;所有成员都分配了空间4+4+1=9,不是结构的字节边界数(sizeof(int))的倍数,所以填充三个字节以满足结构的大小为sizeof(int)的倍数,这样总的空间大小为4+4+4=12。
大雅新科技有限公司
2024-11-19 广告
这方面更多更全面的信息其实可以找下大雅新。深圳市大雅新科技有限公司从事KVM延长器,DVI延长器,USB延长器,键盘鼠标延长器,双绞线视频传输器,VGA视频双绞线传输器,VGA延长器,VGA视频延长器,DVI KVM 切换器等,优质供应商,... 点击进入详情页
本回答由大雅新科技有限公司提供
CNnumen911
2010-03-07 · TA获得超过1133个赞
知道小有建树答主
回答量:401
采纳率:100%
帮助的人:678万
展开全部
这个和字节填充有关, 假设内存每行能够存储4个字节的数据(从你说的情况看, 应该是每行存4个字节),当每行的后面不足以存放下一个变量时,则将这个变量存到下一行中, 而上一行中空的字节以0填充...
int类型占4个字节,bool类型一个字节
则第一种存储顺序下,第一行正好放下int(4字节),然后将两个bool类型的变量存到第二行中(实际只占了2个字节,但是后面的被填充了)所以这种情况下总的大小事8个字节...

第二种情况下, 第一行先存bool,占一个字节,这行的后面还有三个字节, 在存int时,发现后面的存不下了,于是存到下一行,上一行后面的三个字节就被填充掉了, 在存最后一个 bool时有新起了 一行,所以这种情况下总的大小是12字节...

(上面说的不完全准确, 但对于你理解这题完全够了,就是个字节填充的问题)
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
shercoon
2010-03-07 · TA获得超过673个赞
知道答主
回答量:238
采纳率:0%
帮助的人:93.3万
展开全部
这跟内存的布局有关的。在计算机中在对内存读写的时候如果内存对齐的话速度会比较快。
而字节大小是不一样的,为了达到对齐的目的,计算机就会在成员之间填充字节,这样最后的结果就是占用内存变大了。
你也可以禁止这种优化
使用这个#pragma pack()
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
basic13
2010-03-06 · TA获得超过2759个赞
知道大有可为答主
回答量:1782
采纳率:0%
帮助的人:1507万
展开全部
bool就是这样,几种不同类型的变量组合成一个整体的时候,bool类型的变量放在一起占用的内存空间就小
你可以定义一个class:
{
int a;
bool b;
bool c;
bool d;
bool e;
}
你sizeof看一下,你会发现这个也是占用8字节
在int后的4个字节空间里你放一个bool或者放四个bool,整个class所占的内存空间是一样的。

如果你把int改成double
占用空间变成16字节了,一样的道理
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式