1. 计算普通变量所占的内存空间:
char str[]=”hello”;
char *p=str;
int n=10;
sizeof(str)= 6 ; //字符串最后有一个”\n”,strlen(str)则是5.
sizeof(p)= 4 ; //指针占四个字节
sizeof(n)= 4 ; //int占四个字节
void func(char str[100])
{
Sizeof(str)= 4 ; // str作为函数参数传进来,表示一个指针,占四个字节。
}
Void *p=malloc(100);
Size0f(p)= 4; //p是一个指向100字节的内存的指针,同样只占四个字节。
2. 计算类对象所占的空间。
…
Class a{
Public:
Int I;};
Class b{
Public:
Char a;};
Class c{
Public:
Int I;
Short j;};
Class d{
Public:
Int I;
Short j;
Char ch;};
Class e{
Public:
Int I;
Short j;
Char ch;
Char chr;};
Int main(){
Cout<<sizeof(int)<<endl; //4
Cout<<sizeof(short)<<endl; //2
Cout<<sizeof(char)<<endl; //1
Cout<<sizeof(a)<<endl; //4
Cout<<sizeof(b)<<endl; //1
Cout<<sizeof(c)<<endl; //8,4+2+2(字节对齐,使整体是最大基本类型的整数倍。
Cout<<sizeof(d)<<endl; //8,4+2+1+1(字节对齐)
Cout<<sizeof(e)<<endl; //8
}
字节对齐:一些平台对某些特定类型的数据只能从某些特定地址开始存取,然而其他平台可能没有这种情况。为了提高效率,要求工作对数据进行对齐。如,有些平台每次都是从偶地址开始读入,如果一个int型(假如为32位系统)存放在偶地址开始的地方,那么一个读周期就可以读出,而存放在奇地址开始的地方,会需要2个读周期,并对两次读出的结果的高地字节进行拼凑才能得到该int数据。显然读取效率会低。
字节对齐的细节与编译器实现相关,一般而言,需要满足3个准则。
1. 结构体变量的首地址能够被其最宽的基本类型成员的大小所整除。
2. 结构体每个成员相对与结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字。
3. 机构体的总大小为机构题最宽的基本类型成员的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。 如:
Struct s {
Char c1; //4
Int I; //4
Char c2; //4};
Struct st9 {
short i; //4
int m; //4
short d; //4
/ /结构体占4 字节。
struct {
short p; //8
double e; //8
bool b; //8}
};
sizeof计算含有虚函数的类对象的空间大小。
。。。
Class Base{
Public:
Base(int x):a(x){}
Void print(){Cout<<”base”<<endl;}
Private:
Int a;};
Class Derived:public Base{
Public:
Derived(int x):Base(x-1),b(x) {} //构造函数要对父类的变量进行初始化。
Void print(){Cout<<”derived”<<endl;}
Private:
Int b;};
Class A{
Public:
A(int x):a(x){}
Virtual void print(){Cout<<”A”<<endl;}
Private:
Int a;};
Class B:public A{
Public:
B(int x):A(x-1),b(x){}
Virtual void print(){Cout<<”B”<<endl;}
Private:
Int b;};
Int main(){
Base obj1(1);
Cout<<”size of Base obj is”<<sizeof(obj1)<<endl;//4,也就是sizeof(Int),print()不占内存
Derived obj2(2);
Cout<<”size of Derived obj is “<<sizeof(obj2)<<endl;//8,比base类多一个整型成员,因而占8个字节。
A a(1);
Cout<<”size of A obj is”<<sizeof(a)<<endl;//因为其多了一个虚函数,因此占用的内存除了一个整型变量以外,还包括一个隐含的虚含的虚表指针成员,一共是8字节。
B b(2);
Cout<<”size of B obj is”<<sizeof(b)<<endl;//12,比A多了一个int b成员。
Return 0;}
sizeof计算虚拟继承的类对象的空间大小。
。。。
Class a{};
Class b{};
Class c:public a,public b{};
Class d:virtual public a{};
Class e:virtual public a,virtual public b{};
Class f{
Public:
Int a; static int b;}
Int f::b=10;
Int main(){
Cout<<”sizeof(a)=”<<sizeof(a)<<endl;//1,由于A是空类,编译器会安插一个char空类,标记它的每一个对象,因此其大小为1字节。
Cout<<”sizeof(b)=”<<sizeof(b)<<endl;//1,同a
Cout<<”sizeof(c)=”<<sizeof(c)<<endl;//1,类c是多重继承自a和b,其大小认为1.
Cout<<”sizeof(d)=”<<sizeof(d)<<endl;//4,类d是虚继承自a,编译器为该类安插一个指向父类的指针,指针大小为4,由于此类有了一个指针,编译器不会安插一个char了。
Cout<<”sizeof(e)=”<<sizeof(e)<<endl;//8,他有指向父类a和b的两指针。
Cout<<”sizeof(f)=”<<sizeof(f)<<endl;//4,类含有一个静态成员变量,这个静态成员的空间不在类的实例中,而是像全局变量一样在静态存储区中,被类共享,因此其大小是4字节。}
6. 用sizeof()计算数组占的空间的时候,要注意的。
1. void func(char str[100]){ sizeof(str)==4,因为str在此时是指针,只占4字节。}
2. char str[100]; sizeof(str)=400;其代表的则是数组str所占的内存大小。
3. int a=sizeof(str)/sizeof(str[0])=100; 其为计算数组中的个数。
7. sizeof计算联合体的大小。
Union u{double a; int b;};
Union u2{char a[13];int b;};
Union u3{char a[13];char b;};
Int main(){
Cout<<sizeof(u)<<endl;//8,以8字节对齐。结构体的大小取决于占最大的那个。
Cout<<sizeof(u)<<endl;//16,以成员中所占内存最大的成员对齐,虽说13最大,但里面有4,总大小必须是每个成员的整数倍,所以为16。
Cout<<sizeof(u)<<endl;//13。
Return 0;}
使用 ”#pragma pack(x)” 可以改变编译器的对齐方式。如:
#pragma pack(2)
Union u{char buf[9];int a;};
Int main(){
Cout<<sizeof(u)<<endl;//10, 因为最大为9,以2对齐的话,就10了。
Return 0;}
上面是自己的读书笔记和在网上收集的资料,再加上自己的一些理解。
本人的csdn空间:http://blog.csdn.net/frenized_ox/article/details/7345138别说我是抄袭的就是了。
最近在看数据结构了,里面好多安逸的哦。。问到学长说,面试都考数据结构什么的,哎。。大一时候学的,忘了好多,就连希尔排序都忘了。。现在要补了。。最近在学web,好多都不懂,到处碰壁,还是学C++容易点啊。希望各位大哥大姐多多支教,小弟感激不尽!!