关于数据对齐问题

今天看面试宝典时遇到一个问题如下:

class A{

public:

double d;

float a;

int b;

char c;

A();

~A();

};

int mian()

{

cout<<sizeof(A);

}

以我对数据对齐的理解,d为8个字节,那么a,b,c均占8个字节,但是实际上是24个字节(在vc中测试的结果)。后来我打印出它的地址发现,&A.d=0x0012ff58,&A.a=0x0012ff60,&A.b=0x0012ff64,&A.c=0x0012ff68;

由此知道,d占八个字节,而float和int各占四个字节,但是依据数据对齐原理:对于n字节的元素(n=2,4,8,。。。),它的首地址能被n整除才能获得最好的性能。所以c只需一个字节即可,但是实际上编译器为A.c申请了8个字节。测试如下:

int main()

{

int test1;

A testA;

int test2;

printf("%08x %08x %08x %08x %08x %08x\n",&test2,&AA.d,&AA.a,&AA.b,&AA.c,&test1);

}

执行的结果为:0x0012ff54 0x0012ff58 0x0012ff60 0x0012ff64 0x0012ff68 0x0012ff70

由于test1、testA、test2等都是局部变量,均在栈中分配,且test1的地址高,而testA的地址较低,以此类推

从结果可以看出,testA的起始地址是0x0012ff58,结束地址为0x0012ff70,说明结构体A中的c分配了8个字节的空间。

结论:在编译器为变量分配内存时,会依据类型大小最大的变量来对齐(如double),如果有比着小的数据类型并且可以遵循数据对齐原理(上面所述)就是说下一个变量的开始地址必须是它本身的n倍才行,可以按找它自己的大小来分配(如int、float加起来真好是8个字节和double对齐),最后虽然c只是占用一个字节,但是在此结构体中需要和double对齐,所以也占据8个字节的空间,如果在c的后面加上多个char类型的变量(别超过7个),整个结构体的大小不会变,还是24,或者加入一个int型的变量,整个结构体的大小还是24。有了这些知识后看下面一个例题:

class B{

public:

bool m_bTemp;

int m_nTmep;

bool m_bTemp2;

};

class C{

public:

int m_nTmep;

bool m_bTemp;

bool m_bTmep2;

}

cout<<sizeof(B)<<endl;

cout<<sizeof(C)<<endl;




执行结果为:

12

8

在内存中的布局为:

类B:

| bool l ------ | ------ | ------ |

| --------------int-------------- |

| bool | bool | ------ | ------ |

类C:

| --------------int-------------- |

| bool | bool | ------ | ------ |

另外需要注意的是:char *str=“dafddsfasdfasdf”;

char str2[]="dfadfasdfasdf";

sizeof(str)=4;//仅仅是一个指针大小

sizeof(str2)=14;//包含\0的字符串大小

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章