看到阿里的一道笔试题:
#pragma pack(2) class A { int i; union U { char buff[13]; int i; }u; void foo() { } typedef char* (*f)(void*); enum{red, green, blue} color; }a;答案应该是多少呢:22
因为对于u是14个字节,因为u要设定为每一个类型的整数倍,且能容纳类型变量字节的最大值,但是这里有这样一个宏
#pragma pack(2),这个编译器提供的宏能使变量一n字节的方式对齐,谢谢pxhero2012的指正
既然这样,我们顺便来总结一下c++中类的内存大小:
这是一个总结:
#include <iostream> #include <iomanip> using namespace std; class A1//c++要求每个实例在内存中都有独一无二的地址,空类也会被实力化,编译器自动添加一个字节 {}; class A2 { int a; char p; }; class A21//所有类型都小于处理器的大小,优化为最大类型的整数倍 { int a; char b; char c[6]; }; class A22//单个字符存储,不会优化 { char b; char c[5]; }; class A23//double大于处理器位数,以处理器位数对齐 { int a; double b; char c[2]; char d[7]; }; class B//含有虚函数的类中自动维护一个指向虚函数表的指针,大小为4字节 { public: B(){} virtual ~B(){} private: int a; char *b; }; class C: public B { public: C(){} ~C(){} virtual void func();//父类和子类共享一个 vptr,而不管虚函数的个数 private: int x; }; int main() { cout<<"A1:"<<setw(4)<<sizeof(A1)<<endl; cout<<"A2:"<<setw(4)<<sizeof(A2)<<endl; cout<<"A21:"<<setw(4)<<sizeof(A21)<<endl; cout<<"A22:"<<setw(4)<<sizeof(A22)<<endl; cout<<"A23:"<<setw(4)<<sizeof(A23)<<endl; cout<<"B:"<<setw(4)<<sizeof(B)<<endl; cout<<"C:"<<setw(4)<<sizeof(C)<<endl; return 0; }
对于c++关于继承层次的内存布局,准备去看《inside the c++ object module》
今天又看到了这样的题目:再补上一道题
struct P1 { int i; char c; int j; char d; }; struct P2 { int i; char c; char d; int j; }; struct P3 { short w[3]; char c[3]; }; struct P4 { short w[2]; char *c[3]; struct P1 { int i; char c; int j; char d; }; struct P2 { int i; char c; char d; int j; }; struct P3 { short w[3]; char c[3]; }; struct P4 { short w[2]; char *c[3]; struct P1 { int i; char c; int j; char d; }; struct P2 { int i; char c; char d; int j; }; struct P3 { short w[3]; char c[3]; }; struct P4 { short w[3]; char *c[3]; }; struct P5 { struct P1 a[2]; struct P2 *p; }; printf("%d\n",sizeof(P1));//16 printf("%d\n",sizeof(P2));//12 printf("%d\n",sizeof(P3));//10 printf("%d\n",sizeof(P4));//20 printf("%d\n",sizeof(P5));//36
前几个都没有问题,第四个,这里c的大小的是4字节,所以以4个字节对齐