1。今天看群里讨论次问题,发觉自己这方面还真欠缺。以前的想法都是错误的。现更新列出来。
我自己的编译器是vc 6.0。int:4bye char 1:1byte float:4byte double:8byte short:2byte
关于提取结构体大小有几个大的原则:
no1:结构体各成员变量起始地址相对结构体起始地址的偏移量必须为该变量的类型所占用的字节的整数倍数。多余部分编译器会进行填充
no2:结构体大小为其最宽成员基本类型的整数倍
例子:
struct A{
char a;
int i;
}A;
--->sizeof(A)=8 分析:首先成员a的起始地址相对结构的偏移量为0,分配1个字节,此时在来看第二个成员变量i,此时该偏移量为1,不是4的整数倍,因此我们进行填充,
当填充偏移量到4,我们给i分配4个字节。此时A的大小为8字节,为最宽成员基本类型的大小的整数倍。满足原则。
struct A{
char a[];
}A;
sizeof(A)=1,这里虽然没有给字符数组成员分配大小,但是我们编译器会给其分配一个字节。
但是:如果有其他成员,一般不会给他分配内存。
struct A{
char a[];
int i;
}A;
sizeof(A)=4,这里并没有给char a[]分配内存。
我们来看下有成员指针的情况。
struct A{
char c1;
char c2;
char c3;
char c4;
char *p;
char c5;
}A
sizeof(A)=12。这里仍然采用上面的原则。指针占用4个字节,要给他分配内存,需要看其偏移量是不是4的倍数。
而且A的大小要是指针大小的倍数。
下面我们来看嵌套;
typedef struct A{
char b;
int a;
double c;
}A;
typedef struct B{
char b;
double c;
int i;
A a;
char *p;
}B;
sizeof(B)=48;在结构体B中虽然多了一个非基本类型A,但是不影响我们进行分析。在进行内存分析。我们将A a,看成上面的结构体,直接点说。就是将结构体A的成员直接搬进来B中,取代A a; 这样采用内存分析仍然是上面的策略。B的大小是这些基本类型大小的整数倍。