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)
原文地址: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)
相关文章推荐
- 结构体里的“位域”(bit-field)结构
- 实例讲解c语言结构体大小 sizeof(struct A)
- 结构体的大小的计算与空间的优化--之位域字段
- 结构体(struct) 的 sizeof 大小
- sizeof进行结构体大小的判断 (包含位域),讲解详细
- 再谈sizeof——struct 结构存储空间的大小:与成员的顺序、#progma pack参数有关系
- 结构体的大小的计算与空间的优化--之位域字段
- C语言结构体的大小——内存对齐和位域的使用
- 结构体内存对齐后所占内存空间大小的计算
- C语言结构体 —— sizeof(struct)
- sizeOf计算空间大小的总结
- 结构体的内存对齐方式(结构体大小计算 sizeof)(
- struct和nuion、类的补齐规则,以及sizeof求大小
- C语言位域与结构体的内存大小
- sizeof()计算结构体的大小
- c# 结构体struct包含数与byte类型的转换(二)
- sizeof计算struct大小
- (必看)C结构体与C结构体之位域(位段)的sizeof问题.
- sizeof(struct )大小讨论
- struct union数据对齐和sizeof大小