剖析 C++中的结构体与sizeof

来源:互联网 发布:最好的网络兼职平台 编辑:程序博客网 时间:2024/04/29 02:31

提问的帖子:

#include<iostream.h>
class Base
{
public:
int x;
int y;
int h[2];
char a;
char b[3];
char c[1];
};
void main()
{
Base dd;
cout << sizeof(dd) << endl;
}
为什么结果输出为24?

帖子地址:http://community.csdn.net/Expert/topic/5478/5478106.xml?temp=.6268732

//----------------------------------------------------------

1) struct MyStruct
{
 int dda;
 int dda1;
 double type ;
 short duan ;
 int xx;
 int ss;
 int kk;
};//输出

s        0x0012FF60
&s.dda   0x0012FF60
&s.dda1  0x0012FF64
&s.type  0x0012FF68
&s.duan  0x0012FF70
&s.xx    0x0012FF74
----------------------------------
32
32
0
4
8
16
20
24
28
Press any key to continue

2) struct MyStruct
{
 int dda;
 double dda1;
 int type ;
 short duan ;
 int xx;
 int ss;
 int kk;
};

输出:

s        0x0012FF58
&s.dda   0x0012FF58
&s.dda1  0x0012FF60
&s.type  0x0012FF68
&s.duan  0x0012FF6C
&s.xx    0x0012FF70
----------------------------------------
40
40
0
8
16
20
24
28
32
Press any key to continue


s        0x0012FF60
&s.dda   0x0012FF60
&s.dda1  0x0012FF68
&s.type  0x0012FF6C
&s.duan  0x0012FF70
&s.xx    0x0012FF74
----------------------------------------
32
32
0
8
12
16
20
24
28
Press any key to continue

 


void main()
{
 MyStruct s;
 cout << "s        " << &s << endl;
 cout << "&s.dda   " << &s.dda << endl;
 cout << "&s.dda1  " << &s.dda1 << endl;
 cout << "&s.type  " << &s.type << endl;
 cout << "&s.duan  " << &s.duan << endl;
 cout << "&s.xx    " << &s.xx << endl;
 
 cout<< "----------------------------------------" << endl;
 
 cout<<sizeof(MyStruct)<<endl ;
 cout<<sizeof(s)<<endl ;
 
 cout<<offsetof(MyStruct,dda)<<endl ;
 cout<<offsetof(MyStruct,dda1)<<endl ;
 cout<<offsetof(MyStruct,type)<<endl ;
 cout<<offsetof(MyStruct,duan)<<endl ;
 cout<<offsetof(MyStruct,xx)<<endl ;
 cout<<offsetof(MyStruct,ss)<<endl ;
 cout<<offsetof(MyStruct,kk)<<endl ;
}

3) struct MyStruct
{
 double dda;
 int dda1;
 int type ;
 short duan ;
 int xx;
 int ss;
 int kk;
};
输出:

//----------------------------------------------------------

C++中的结构体与sizeof

       前几天在C/C++版上看到一个关于“对齐”和“sizeof”的问题。原来一直以为自己已经把这个问题弄清楚了,但是看了帖子之后才发现仍有许多概念模糊的地方,于是把MSDN翻出来细细看了一下,又做了几个小试验验证自己的想法,并作此文,作为自己对这个问题的一个阶段性小结。文中若有不对之处,望各位大侠批评指正。
 
影响结构体的sizeof的因素:
1) 不同的系统(如32位或16位系统):不同的系统下int等类型的长度是变化 的,如对于16位系统,int的长度(字节)为2,而在32位系统下,int的长度为4;因此如果结构体中有int等类型的成员,在不同的系统中得到的sizeof值是不相同的。
2)  编译器设置中的对齐方式:对齐方式的作用常常会让我们对结构体的sizeof值感到惊讶。
 
对齐
为了能使CPU对变量进行高效快速的访问,变量的起始地址应该具有某些特性,即所谓的“对齐”。例如对于4字节的int类型变量,其起始地址应位于4字节边界上,即起始地址能够被4整除。变量的对齐规则如下(32位系统):
Type
Alignment
char
在字节边界上对齐
short (16-bit)
在双字节边界上对齐
int and long (32-bit)
在4字节边界上对齐
float
在4字节边界上对齐
double
在8字节边界上对齐
structures
单独考虑结构体的个成员,它们在不同的字节边界上对齐。
其中最大的字节边界数就是该结构的字节边界数。
 
MSDN原话:Largest alignment requirement of any member
 
理解结构体的对齐方式有点挠头,如果结构体中有结构体成员,那么这是一个递归的过程。
 
对齐方式影响结构体成员在结构体中的偏移
设编译器设定的最大对齐字节边界数为n,对于结构体中的某一成员item,它相对于结构首地址的实际字节对齐数目X应该满足以下规则:
X = min(n, sizeof(item))
例如,对于结构体 struct {char a; int b} T;
当位于32位系统,n=8时:
a的偏移为0,
b的偏移为4,中间填充了3个字节, b的X为4;
 
当位于32位系统,n=2时:
a的偏移为0,
b的偏移为2,中间填充了1个字节,b的X为2;
 
结构体的sizeof
设结构体的最后一个成员为LastItem,其相对于结构体首地址的偏移为offset(LastItem),其大小为sizeof(LastItem),结构体的字节对齐数为N,则:
 
结构体的sizeof 为: 若offset(LastItem)+ sizeof(LastItem)能够被N整除,那么就是offset(LastItem)+ sizeof(LastItem),否则,在后面填充,直到能够被N整除。
 
例如:32位系统,n=8,
结构体 struct {char a; char b;} T;
 struct {char a;  int b;} T1;
 struct {char a; int b; char c;} T2;
 
sizeof(T) == 2;      N = 1   没有填充
sizeof(T) == 8;      N = 4   中间填充了3字节
sizeof(T2)==12;    N = 4   中间,结尾各填充了3字节
 
    注意:
1) 对于空结构体,sizeof == 1;因为必须保证结构体的每一个实例在内存中都有独一无二的地址。
2) 结构体的静态成员不对结构体的大小产生影响,因为静态变量的存储位置与结构体的实例地址无关。例如:
struct {static int I;} T;      struct {char a; static int I;} T1;
sizeof(T) == 1;            sizeof(T1) == 1;
    3) 某些编译器支持扩展指令设置变量或结构的对齐方式,如VC,
详见MSDN(alignment of structures)
 

 可学习参考得其他关于对齐的帖子:

http://www.cppblog.com/cc/archive/2006/08/01/10765.html

http://blog.csdn.net/wqf363/archive/2006/11/26/1415628.aspx

http://blog.csdn.net/yanjun_1982/archive/2005/10/17/507871.aspx

http://dev.csdn.net/article/56/56202.shtm

http://dev.csdn.net/article/48/48195.shtm

http://www.google.cn/search?complete=1&hl=zh-CN&newwindow=1&rls=com.microsoft:zh-cn:IE-SearchBox&rlz=1I7GGLJ&q=%E5%AD%97%E8%8A%82%E5%AF%B9%E9%BD%90&suggest=0&sa=X&oi=cjkrefinements&ct=result&cd=1

http://www.google.cn/search?complete=1&hl=zh-CN&newwindow=1&rls=com.microsoft:zh-cn:IE-SearchBox&rlz=1I7GGLJ&q=%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90&suggest=1&sa=X&oi=cjkrefinements&ct=result&cd=2

----------------------------------

<script type="text/javascript"><!--google_ad_client = "pub-2019358045871963";google_ad_width = 336;google_ad_height = 280;google_ad_format = "336x280_as";google_ad_type = "text_image";google_ad_channel = "";//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>