转载:https://i-blog.csdnimg.cn/blog_migrate/3f086a1bfcc9dfab0d329b5b8f84dde6.png
对于sizeof,作个简单的总结:
在一个struct或者class里面定义的一些变量,
1、如果是static类型的,则不算入sizeof计算范围(可能是因为创建对象时,static类型不属于某个特定的对象,而是属于这个类所有的对象,它在内存中不是和对象的变量一起存放的);
2、一般的函数也不算入sizeof计算范围,虚函数则放到一个虚函数表中,有一个虚函数表指针指向这个表格(无论有多少个虚函数,都是加上4 ,记住了)。如果是单继承,则子类的大小是父类的大小加上自己的大小。
3、在一个struct或者class里面定义的变量,如果要计算其大小,那么首先应该找出类型最大的那个,然后以那个大小来进行“内存对齐”,最后就可以得到真实的大小了(一般情况下是这样)。
具体举例如下(部分测试代码来源于:http://blog.csdn.net/fanfanK/article/details/12175585)
- #include<iostream>
- #include<stdio.h>
- using namespace std;
- class TwoIntNoVirtual
- {
- int a;
- int b;
- void function()
- {
- cout << "Hello" << endl;
- }
- };
- class TwoIntOneVirtual
- {
- int a;
- int b;
- virtual void function()
- {
- }
- };
- class TwoIntTwoVirtual
- {
- int a;
- int b;
- virtual void function()
- {
- }
- virtual void function2()
- {
- }
- };
- class TwoIntOneVirtualDerived : public TwoIntOneVirtual
- {
- void function2()
- {
- }
- };
- class TwoIntTwoVirtualDerived : public TwoIntTwoVirtual
- {
- void function()
- {
- }
- void function2()
- {
- }
- };
- class OtherTest
- {
- char e, f, g, h, i, j, k;
- int a;
- int b;
- int c;
- long long d;
- virtual void function() {}
- virtual void function2() {}
- };
- class node0
- {
- public:
- int a;
- char b;
- short c;
- char d;
- double e;
- };
- int main()
- {
- cout << "TwoIntNoVirtual: " << sizeof(TwoIntNoVirtual) << endl; // 8
- cout << "TwoIntOneVirtual: " << sizeof(TwoIntOneVirtual) << endl; // 12
- cout << "TwoIntTwoVirtual: " << sizeof(TwoIntTwoVirtual) << endl; // 12
- cout << "TwoIntOneVirtualDerived: " << sizeof(TwoIntOneVirtualDerived) << endl; // 12
- cout << "TwoIntTwoVirtualDerived: " << sizeof(TwoIntTwoVirtualDerived) << endl; // 12
- cout << "OtherTest: " << sizeof(OtherTest) << endl; // 40
- cout << "Long long: " << sizeof(short) << endl; // 2
- cout << "Long long: " << sizeof(long long) << endl; // 8
- cout << "node0: " << sizeof(node0) << endl; // 24
- cout << "---------------------" << endl;
- node0 no;
- cout << "&a = " << (void*)&no.a << endl;
- cout << "&b = " << (void*)&no.b << endl;
- cout << "&c = " << (void*)&no.c << endl;
- cout << "&d = " << (void*)&no.d << endl;
- cout << "&e = " << (void*)&no.e << endl;
- return 0;
- }
在这个例子中,下面这个比较有代表性:
- class node0
- {
- public:
- int a;
- char b;
- short c; //short占2个字节
- char d;
- double e;
- };
这里,首先找到大小最大的类型为double,占8个字节,所以应该以8字节的大小来对齐,最后的大小应该是8的整数倍。
现在已经找到最大的为8了,下面就来模拟对上面结构来开内存(以下表格表示内存,地址从上到下、从左到右的方向增加),表格里的字母表示该地址被字母所表示的变量占据着,空格是为了要对齐才这样的。
再分析一个:
- class OtherTest
- {
- char e, f, g, h, i, j, k;
- int a;
- int b;
- int c;
- long long d;
- virtual void function() {}
- virtual void function2() {}
- };
这里,也是首先找到大小最大的类型,为long long,在Windows7 32位的VS2013上占8个字节,所以应该以8字节的大小来对齐,最后的大小应该是8的整数倍。
现在已经找到最大的为8了,下面就来模拟对上面结构来开内存(以下表格表示内存,地址从上到下、从左到右的方向增加),表格里的字母表示该地址被字母所表示的变量占据着,空格是为了要对齐才这样的。其中vptr是虚函数表指针,一般占4个字节。所以总共是40字节长。
如果是在GCC下,那么sizeof的结果是32,内存如下: