1.结构体对齐
struct s1
{
int a;
char b;
double c;
};
struct s2
{
char a;
double b;
int c;
};
//16 24
VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节.
2.对齐原因
①平台原因(移植原因):各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取,否则会抛出异常。
②性能原因:经过内存对齐后,cpu的访问速度会得到大大的提升。原因在于,大部分的处理器都会以双字节、4字节、8字节等作为单位来存取内存(在cpu眼中,内存都是一块一块的),假设处理器以4字节的存取粒度处理,则该处理器只能从地址为4的倍数的内存开始读取数据,如果没有内存对齐,当cpu处理一个以地址1开始的int类型的变量时,先访问地址0—3处内存,在访问4—7的,需要访问两次内存才能读取数据,如果内存对齐,则处理器只需访问一次内存就可以读取数据,效率提高了很多(理论上对任何类型的变量访问可以从任何地址开始,但实际的计算机系统对基本类型的数据在内存中的存放位置有着限制)。
#pragma pack()
//设置默认对齐数
3.结构体成员超界
#include <stdio.h>
#include <string.h>
typedef struct{
int iTest;
char pcArray[20];
int iParam;
}s;
main(){
s s1;
s1.iParam = 5;
s1.iTest = 6;
printf("iTest:\t%p:%d\n",&s1.iTest,s1.iTest);
printf("iParam:\t%p:%d\n",&s1.iParam,s1.iParam);
strncpy(s1.pcArray,"Hello World,Hello World",23);
printf("pcArray:\t%p:%s\n",&s1.pcArray,s1.pcArray);
printf("iTest:\t%p:%d\n",&s1.iTest,s1.iTest);
printf("iParam:\t%p:%d\n",&s1.iParam,s1.iParam);
}
//结果
//[root@j struct]# gcc array.c
//[root@j struct]# ./a.out
//iTest: 0xbfbebc64:6
//iParam: 0xbfbebc7c:5
//pcArray: 0xbfbebc68:Hello World,Hello World
//iTest: 0xbfbebc64:6
iParam: 0xbfbebc7c:6581362
s1.pcArray字符串超界,iParam的内容发生了修改