您的位置:首页 > 其它

sizeof(struct{bit-field})——包含位域的结构体的空间大小

2015-03-21 02:07 309 查看
原文:sizeof(struct)

原文地址:http://blog.sina.com.cn/s/blog_913c070a0100zq3m.html

一般情况下,编译器会把struct中的成员作对齐处理,所以sizeof后不是等于所以成员大小之和。

VC编译器做对齐处理的步骤如下(原作者理解):

1、首先获得struct中的大小最大的基本数据类型成员的大小,称为内存分配基大小(以下简称:基大小),这里的最大成员为double d1,d1的大小为8,所以基大小为8;

2、按照顺序为struct中的成员分配内存:

(1)、分配一个大小等于基大小的内存;

(2)、从第一个到最后一个成员,取得每个成员的大小为N,调整可插入内存起始地址,使得(可插入内存起始地址 - struct起始地址) 为N的倍数(向后移调整),从可插入内存起始地址 开始插入成员,如果分配的剩余空间大于这个成员的大小,则把struct的成员插进内存中,否则执行(1)。直到把所有成员插完为止。

3、此时struct的大小应该为基大小的倍数。

例如,

struct s{

double d1;

int d2;

char d3;char d4;

};

内存分配情况如下:

8(double)+ 8(int+char+char=6)= 16

我把笔试原题深化一下,测试了一些原文没写到的地方(位域bit-field),过程如下:

首先是编译器关于位域大小的区别,VC中位域大小不能大于类型大小,而Dev-C++中可以。

即 int i1:33; 在Dev-C++中合法,在VC中不合法。

因为一般在Dev-C++上写简短代码,我在这个问题浪费了很多时间,以后还是用VC吧。。

虽然没什么意义,还是贴出Dev-C++运行结果吧:

sizeof(struct{int i:32;})==4

sizeof(struct{int i:64;})==8

sizeof(struct{int i:65;})==16 //65

sizeof(struct{int i:128;})==16

sizeof(struct{int i:192;})==24

sizeof(struct{int i:256;})==32

可见位域大小开始每次增加4byte,8byte以后每次增加8byte(Dev-C++,48byte后未测试)

测试之前以为是像String类一样每次翻倍(String类这样操作可以减少空间大小变化次数,位域其实不存在这个问题,为什么不每次都加4byte呢?)。

然后我输出了一下每一项的地址:

struct Node

{

char c1,c2;//2

short s1,s2;//4

unsigned int i1:2,i2:3; // Node* o; &(0->i1);发生错误,不能获得位域的地址

Node* n;//4

};//28

Node* o = new Node();

cout<<sizeof(*o)<<"\n";

cout<<"o----"<<o<<"\n";

cout<<"c1---"<<&(o->c1)<<"\n";

cout<<"c2---"<<&(o->c2)<<"\n";

cout<<"s1---"<<&(o->s1)<<"\n";

cout<<"s2---"<<&(o->s2)<<"\n";

cout<<"n----"<<&(o->n)<<"\n";

VC输出结果为:

16

o----003GADE0

c1---??????E0

c2---??????E1

s1---??????E2 //4

s2---??????E4

n----??????EC //4

Dev-C++输出结果为:

12

o----0x??????34

c1---0x??????34

c2---0x??????35

s1---0x??????36 //4

s2---0x??????38

n----0x??????4c //4

i1/i2位于s2/n之间,可以看出,VC中s2/i1/i2共占8byte,Dev-C++中s2/i1/i2共占4byte。(我推测VC中,s2占2byte填为4byte,i1/i2同类型合并5bit填27bit;而Dev-C++则把s2/i1/i2填为4byte)

另外,我本来以为基会按从大到小的顺序排列。(根据sizeof(struct)原文最后一段,VC不对成员作优化排列,g++对成员作优化排列)

其他阅读:文章《c/c++数组与sizeof的基础知识》(http://www.cppblog.com/bloodsuck/articles/7575.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: