关于sizeof的笔试面试题详解

原创Blog,转载请注明处处

 http://blog.csdn.net/hello_hwc

注意:sizeof是编译期计算出结果的,这一点对后面的理解很重要

一、关于结构体

先看下代码

#include "stdafx.h"  
#include <iostream>  
using namespace std;  
typedef struct    
{  
    char a:3;  
    char b:3;  
    char c:3;  
    char d:3;  
    char e:3;  
}test1;  
typedef struct    
{  
    char a:3;  
    char b:4;  
    char c:5;  
    char d:6;  
    char e:7;  
}test2;  
typedef struct    
{  
    char a:1;  
    char b:2;  
    char c:3;  
    char d:4;  
    char e:5;  
}test3;  
typedef struct{  
    int a;  
    char b;  
    char d;  
    long c;  
}test4;  
typedef struct{  
    int a;  
    char b;  
    long c;  
    char d;  
}test5;  
  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    cout<<sizeof(test1)<<endl;  
    cout<<sizeof(test2)<<endl;  
    cout<<sizeof(test3)<<endl;  
    cout<<sizeof(test4)<<endl;  
    cout<<sizeof(test5)<<endl;  
    return 0;  
}  

 

然后贴上运行结果

解释下为什么

1、对于test1,结果是3Byte。有些同学好奇,3bit*5 = 15bit,不是应该占用2Byte吗?可是计算机没你大脑智能,它管理bit的方式是8bit一组,所以对于一组8bit,只能放下两个3bit,另外2bit没用。所以,对于test1来说,三个Byte是这么分配的。1Byte(3bit,3bit,2bit填充)2Byte(3bit,3bit,2bit填充)3Byte(3bit,5bit填充)

2、对于test2结果是4Byte.有了test1的解释,这里不难理解了吧。我再解释下内存分配。1Byte(3bit,4bit,1bit填充)2Byte(5bit,3bit填充)3Byte(6bit,2bit填充)4Byte(7bit,1bit填充)

3、test3结果是3Byte。和上述两个类似

4、test4的结果是12。为什么不是4+1+1+4呢?(我这里long是4Byte),因为C++对于Byte的管理仍然要内存对齐,我这里的内存对其是4Byte。所以,内存占用是这样的4Byte(Int)4Byte(char,char,2Byte填充)4Byte(long)

5、有些同学会好奇,为什么两个结构体声明换了个顺序,差了4Byte。同样是因为内存对齐

 

二、字符串与char*和char数组

 

// testforyou.cpp : Defines the entry point for the console application.  
//  
  
#include "stdafx.h"  
#include <iostream>  
#include <string>  
using namespace std;  
  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    string s = "hellohwc";  
    char * s1 = "hellohwc";  
    char s2[] = "hellohwc";  
    char s3[100];  
    char* s4=(char*)malloc(100);  
    void *s5=(void*)malloc(100);  
    cout<<sizeof(s)<<endl;  
    cout<<sizeof(s1)<<endl;  
    cout<<sizeof(s2)<<endl;  
    cout<<sizeof(s3)<<endl;  
    cout<<sizeof(s4)<<endl;  
    cout<<sizeof(s5)<<endl;  
    return 0;  
}  

 

运行结果

 

解释下

对于String类型。每个编译器给分配内存的空间都是一定的,我这里是32Byte。所以,不管字符串长度多长,内存分配都是32。当然也有4,16等情况,因编译期不同而不同。

1、char * s1,s1本身是个指针,所以长度是4个字节,跟后面指向什么没关系。

2、s2是数组保存了一个字符串。由于字符串最后一个隐藏的结束符。所以,长度为8+1 = 9

3、s3是数组,在编译期分配了100*1 = 100Byte,所以结果是100

4、s4和s5都是指针,长度4Byte。

三、类

先看代码

 

// testforyou.cpp : Defines the entry point for the console application.  
//  
  
#include "stdafx.h"  
#include <iostream>  
#include <string>  
using namespace std;  
  
class emptyClass1{  
public:  
    emptyClass1(){}  
    ~emptyClass1(){}  
};  
class emptyClass2{  
public:  
    emptyClass2(){}  
    virtual ~emptyClass2(){}  
};  
class hwcBase{  
public:  
    hwcBase(){}  
    virtual  ~hwcBase(){}  
private:  
    int base;  
};  
  
class hwcSubFirst:hwcBase{  
public:  
    hwcSubFirst():hwcBase(){}  
    ~hwcSubFirst(){}  
private:  
    int sub;  
};  
  
class hwcSubSecond:hwcBase{  
public:  
    hwcSubSecond():hwcBase(){}  
    ~hwcSubSecond(){}  
private:  
    int sub;  
    char sub2;  
};  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    cout<<sizeof(emptyClass1)<<endl;  
    cout<<sizeof(emptyClass2)<<endl;  
    cout<<sizeof(hwcBase)<<endl;  
    cout<<sizeof(hwcSubFirst)<<endl;  
    cout<<sizeof(hwcSubSecond)<<endl;  
    return 0;  
}  

 

运行结果

解释下:

1、对于一个空的类,在内存中要存在一个标示来区分,所以即使是空的,也要分配一个字节

2、同样是empty的类,但是有一个虚的析构函数,所以,保存了一个指针(vptr)指向虚表。一个指针4Byte

3、hwcBase类,有一个Int占用4Byte,一个指针(vptr),所以共占用8Byte

3、hwcSubFirst,继承来一个Int,本身有一个Int,加上一个vptr指针,共12字节

4、hwcSubSecond,和hwcSubFirst类似,但是多了一个char,考虑到内存对其,12+4 = 16字节

posted @ 2017-01-22 21:37  typeofGeek  阅读(689)  评论(0)    收藏  举报