网上搜索了一些文章来看,难懂,难理解,而且与我的测试并不相符合
我用下面的js生成c代码
var strstruct = '';
var strcall = '';
var strx = '';
var csize = 0;
var ts = '';
for(i=0;i<64;i++){
//第2、3、4测试用到
if(i%3==1){
strx += " uint i"+i+";\n";
csize+=4;
ts+='i';
}
//第4测试用到
else if(i%3==2){
strx += " ulong i"+i+";\n";
csize+=8;
ts+='l';
}
//第1、3、4测试用到
else{
strx += " ushort i"+i+";\n";
csize+=2;
ts+='s';
}
strstruct += "\
typedef struct{\n\
"+strx+"\n\
}s"+i+";\n";
strcall += ' printf("sizeof(s'+i+')=%d/%d'+ts+'\\n", sizeof(s'+i+'), '+csize+');\n';
}
var str = '#include <stdio.h>\n\
#include <stdlib.h>\n\
#include <dlfcn.h>\n\
#include <string.h>\n\
'+strstruct+'\n\
void main(){\n\
'+strcall+'\n\
}\n';
console.log(str);
进行了4次测试,结果如下:
1、分别打印了有1到64个ushort的struct的长度,发现长度规律为: 成员数 * 2
2、分别打印了有1到64个uint的struct的长度,发现长度规律为: 成员数 * 4
3、生成64个struct,每个struct成员规律为 int short int short,即第n(0开始)个成员的类型 = n%2==0?int:short,发现长度规律为: 成员数 * 4
4、生成64个struct,每个struct成员规律为 short int short int,即第n(0开始)个成员的类型 = n%2==1?int:short,发现长度规律为: 除第一个长度为2委外,其它都是 成员数 * 4
5、生成64个struct,每个struct成员规律为 short int long short int long,即第n(0开始)个成员的类型 = n%3=0?short:(n%3==1?int:long),长度规 members后字符代表成员顺序和类型(s=short, l=long, i = int):
sizeof(s0)=2/2 members:s
sizeof(s1)=8/6 members:si
sizeof(s2)=16/14 members:sil
sizeof(s3)=24/16 members:sils
sizeof(s4)=24/20 members:silsi
sizeof(s5)=32/28 members:silsil
sizeof(s6)=40/30 members:silsils
sizeof(s7)=40/34 members:silsilsi
sizeof(s8)=48/42 members:silsilsil
sizeof(s9)=56/44 members:silsilsils
sizeof(s10)=56/48 members:silsilsilsi
sizeof(s11)=64/56 members:silsilsilsil
sizeof(s12)=72/58 members:silsilsilsils
sizeof(s13)=72/62 members:silsilsilsilsi
sizeof(s14)=80/70 members:silsilsilsilsil
sizeof(s15)=88/72 members:silsilsilsilsils
sizeof(s16)=88/76 members:silsilsilsilsilsi
sizeof(s17)=96/84 members:silsilsilsilsilsil
sizeof(s18)=104/86 members:silsilsilsilsilsils
sizeof(s19)=104/90 members:silsilsilsilsilsilsi
sizeof(s20)=112/98 members:silsilsilsilsilsilsil
sizeof(s21)=120/100 members:silsilsilsilsilsilsils
sizeof(s22)=120/104 members:silsilsilsilsilsilsilsi
sizeof(s23)=128/112 members:silsilsilsilsilsilsilsil
sizeof(s24)=136/114 members:silsilsilsilsilsilsilsils
sizeof(s25)=136/118 members:silsilsilsilsilsilsilsilsi
sizeof(s26)=144/126 members:silsilsilsilsilsilsilsilsil
sizeof(s27)=152/128 members:silsilsilsilsilsilsilsilsils
。。。。。。。。。
规律是长度增加时增加8字节,也就是长度为8的n次方且这个长度能够存下所有成员!
总结结构体长度跟成员的规律:
1、长度增加值根据最长的成员决定:最长的是多长,增加长度时就增加多少。
2、长度大于等于成员本身的长度和
也就是:
1、成员类型相同时,长度为:成员个数*单个成员长度
2、成员类型长度不一样时,假设成员最短为n,最长为m,结构体实际长度l:
a、l % n == 0,l是n的倍数
b、最多浪费的空间为m-n。(这句话只在上面的第4个测试成立)
c、浪费的空间可以使用:
typedef struct {
ushort size;
char key;
ulong nKeyLength;
} StringBucket;
这个的长度是16,key的相对位置是2。3、4、5、6、7个位置是“浪费”的,
但你实际这样是不会出错的:
StringBucket sb;
memcpy((char*)sb +sizeof(ushort), "abcdef", 6);
上面代码并不会越界。
d、成员顺序不同,结构长度不同
typedef struct {
uint size;
char key;
ulong nKeyLength;
} StringBucket;
长度16;
typedef struct {
uint size;
ulong nKeyLength;
char key;
} StringBucket;
长度24;
把长的成员放前面,占空间更小。具体我总结不出规律,用下面的代码,来检查成员的位置:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
typedef struct {
uint size;
ulong nKeyLength;
char key;
} StringBucket;
void printBitOfByte(char $x){
int $y;
for($y=7;$y>-1;$y--){
printf("%d",($x>>$y)&0x01);
}
printf(" ");
}
void printStr(char *str, int len){
char c;
int i=0;
while(1){
c = str[i++];
if(--len<0)
break;
printBitOfByte(c);
if(i%8==0)
printf("\n");
else
printf(" ");
}
printf("\n");
}
void main(){
StringBucket sb;
memset(&sb, 0, sizeof(StringBucket));
sb.size=1;
sb.nKeyLength=3;
sb.key=7;
printf("size=%d\n", sizeof(StringBucket));
printStr((char*)&sb, sizeof(StringBucket));
}
size=24
00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000011 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000111 00000000 00000000 00000000 00000000 00000000 00000000 00000000
可以看出size和key后面都有浪费。
用我上面的代码来优化你的内存占用吧