WinCE 下结构体占用空间的分析
年前辞职了,准备年后找工作。
所以在网上查找一下 C/C++ 基础方面的面试题,个人感觉这方面还是要准备一下。
虽然后面的应聘没有用到所准备的这些,算是学习一下。
在学习过程中,注意到一些关于结构体占用内存空间大小(sizeof 与 padding byte)的问题,觉得挺有趣的。
在 WinCE 以前的小系统(嵌入式系统)编程时,特别注意内存的使用情况;但到了 WinCE 系统后,由于设备一般都有 128M(或更多)的内存,所以在内存的使用与优化上很多人已经不太注意。
嵌入式方面的程序员,还是有必要了解以下关于结构体占用空间这个问题。
1 typedef struct TwoBytes_S 2 { 3 char cOne; 4 char cTwo; 5 }TwoBytesEml; 6 7 8 typedef struct FourBytes_S 9 { 10 char cOne; 11 char cTwo; 12 char cThree; 13 char cFour; 14 }FourBytesEml; 15 16 17 typedef struct EightBytes_S 18 { 19 char cOne; 20 char cTwo; 21 char cThree; 22 char cFour; 23 char cFive; 24 char cSix; 25 char cSeven; 26 char cEight; 27 }EightBytesEml; 28 29 30 // 结构体实际占用的空间大小与结构体中占用空间最大的成员有什么关系? 31 // 结论: 结构体的大小为结构体中占用字节最大的成员的倍数。 32 33 34 // 对比 TestOder, TestOrder3 和 TestOder2 占用内存空间的情况 35 typedef struct TestOrder_S 36 { 37 char cFirst; 38 char cSecond; 39 int iFirst; 40 char cThird; 41 char cFourth; 42 }TestOrder; 43 44 45 typedef struct TestOrder2_S 46 { 47 int iFirst; 48 char cFirst; 49 char cSecond; 50 char cThird; 51 char cFourth; 52 }TestOrder2; 53 54 55 typedef struct TestOrder3_S 56 { 57 int iFirst; 58 char cFirst; 59 char cSecond; 60 char cThird; 61 }TestOrder3; 62 63 64 // 对比 TestShort 和 TestShortEml 占用内存空间的情况 65 typedef struct TestShort_S 66 { 67 char cOne; 68 short sAlign; 69 }TestShort; 70 typedef struct TestShortEml_S 71 { 72 char cOne; 73 TwoBytesEml sAlign; 74 }TestShortEml; 75 76 77 // 对比 TestInt 和 TestIntEml 占用内存空间的情况 78 typedef struct TestInt_S 79 { 80 char cOne; 81 int iAlign; 82 }TestInt; 83 typedef struct TestIntEml_S 84 { 85 char cOne; 86 FourBytesEml iAlign; 87 }TestIntEml; 88 89 90 // 对比 TestDouble 和 TestDoubleEml 占用内存空间的情况 91 typedef struct TestDouble_S 92 { 93 char cOne; 94 double dfAlign; 95 }TestDouble; 96 typedef struct TestDoubleEml_S 97 { 98 char cOne; 99 EightBytesEml dfAlign; 100 }TestDoubleEml; 101 102 103 // #define _USE_WINDOWS_CE_PLATFORM 104 void CalcSizeOfStruct(void) 105 { 106 #ifdef _USE_WINDOWS_CE_PLATFORM 107 RETAILMSG(1,(L"size of char is %d\r\n",sizeof(char))); 108 RETAILMSG(1,(L"size of short is %d\r\n",sizeof(short))); 109 RETAILMSG(1,(L"size of int is %d\r\n",sizeof(int))); 110 RETAILMSG(1,(L"size of long is %d\r\n",sizeof(long))); 111 RETAILMSG(1,(L"size of char * is %d\r\n",sizeof(char *))); 112 RETAILMSG(1,(L"size of float is %d\r\n",sizeof(float))); 113 RETAILMSG(1,(L"size of double is %d\r\n",sizeof(double)); 114 115 // 对比 TestOder, TestOrder3 和 TestOder2 占用内存空间的情况 116 RETAILMSG(1,(L"size of struct(char,char,int,char,char) is %d\r\n",sizeof(TestOrder))); 117 RETAILMSG(1,(L"size of struct(int,char,char,char,char) is %d\r\n",sizeof(TestOrder2))); 118 RETAILMSG(1,(L"size of struct(int,char,char,char) is %d\r\n",sizeof(TestOrder3))); 119 120 // 对比 TestShort 和 TestShortEml 占用内存空间的情况 121 RETAILMSG(1,(L"size of struct(char,short) is %d\r\n",sizeof(TestShort))); 122 RETAILMSG(1,(L"size of struct(char,TwoBytesEml(char,char)) is %d\r\n",sizeof(TestShortEml))); 123 124 // 对比 TestInt 和 TestIntEml 占用内存空间的情况 125 RETAILMSG(1,(L"size of struct(char,int) is %d\r\n",sizeof(TestInt))); 126 RETAILMSG(1,(L"size of struct(char,FourBytesEml(char,char,char,char)) is %d\r\n",sizeof(TestIntEml))); 127 128 // 对比 TestDouble 和 TestDoubleEml 占用内存空间的情况 129 RETAILMSG(1,(L"size of struct(char,double) is %d\r\n",sizeof(TestDouble))); 130 RETAILMSG(1,(L"size of struct(char,EightBytesEml(char,char,char,char,char,char,char,char)) is %d\r\n", 131 sizeof(TestDoubleEml))); 132 #else 133 printf("size of char is %d\r\n",sizeof(char)); 134 printf("size of short is %d\r\n",sizeof(short)); 135 printf("size of int is %d\r\n",sizeof(int)); 136 printf("size of long is %d\r\n",sizeof(long)); 137 printf("size of char * is %d\r\n",sizeof(char *)); 138 printf("size of float is %d\r\n",sizeof(float)); 139 printf("size of double is %d\r\n",sizeof(double)); 140 141 // 对比 TestOder, TestOrder3 和 TestOder2 占用内存空间的情况 142 printf("size of struct(char,char,int,char,char) is %d\r\n",sizeof(TestOrder)); 143 printf("size of struct(int,char,char,char,char) is %d\r\n",sizeof(TestOrder2)); 144 printf("size of struct(int,char,char,char) is %d\r\n",sizeof(TestOrder3)); 145 146 // 对比 TestShort 和 TestShortEml 占用内存空间的情况 147 printf("size of struct(char,short) is %d\r\n",sizeof(TestShort)); 148 printf("size of struct(char,TwoBytesEml(char,char)) is %d\r\n",sizeof(TestShortEml)); 149 150 // 对比 TestInt 和 TestIntEml 占用内存空间的情况 151 printf("size of struct(char,int) is %d\r\n",sizeof(TestInt)); 152 printf("size of struct(char,FourBytesEml(char,char,char,char)) is %d\r\n",sizeof(TestIntEml)); 153 154 // 对比 TestDouble 和 TestDoubleEml 占用内存空间的情况 155 printf("size of struct(char,double) is %d\r\n",sizeof(TestDouble)); 156 printf("size of struct(char,EightBytesEml(char,char,char,char,char,char,char,char)) is %d\r\n", 157 sizeof(TestDoubleEml)); 158 #endif 159 } 160 161 162 // 第二部分 Leo.Zheng 163 struct TstStruct 164 { 165 char *p; 166 char c; 167 long x; 168 }; 169 170 171 struct TstStruct2 172 { 173 char c; /* 1 byte */ 174 char pad[7]; /* 7 bytes */ 175 char *p; /* 4 bytes */ 176 long x; /* 4 bytes */ 177 }; 178 179 180 struct TstStruct3 181 { 182 char *p; /* 4 bytes */ 183 char c; /* 1 byte */ 184 }; 185 186 187 struct TstStruct4 188 { 189 short s; /* 2 bytes */ 190 char c; /* 1 byte */ 191 }; 192 193 194 struct TstStruct5 195 { 196 short s; 197 char c; 198 int flip:1; 199 int nybble:4; 200 int septet:7; 201 }; 202 203 204 struct TstStruct6 205 { 206 char c; 207 struct Struct6_Sub 208 { 209 char *p; 210 short x; 211 } inner; 212 }; 213 struct TstStruct6_R 214 { 215 struct Struct6_Sub 216 { 217 char *p; 218 short x; 219 } inner; 220 char c; 221 short s; 222 }; 223 224 225 struct TstStruct7 226 { 227 char c; 228 struct TstStruct7 *p; 229 short x; 230 }; 231 232 233 struct TstStruct8 234 { 235 struct TstStruct8 *p; 236 short x; 237 char c; 238 }; 239 240 241 struct TstStruct9 242 { 243 struct foo7_inner 244 { 245 char *p; 246 short x; 247 } inner; 248 char c; 249 }; 250 251 252 void CalcSizeOfStruct2(void) 253 { 254 #ifdef _USE_WINDOWS_CE_PLATFORM 255 RETAILMSG(1,(L"size of (struct TstStruct) = %d\n", sizeof(struct TstStruct))); 256 RETAILMSG(1,(L"size of (struct TstStruct2) = %d\n", sizeof(struct TstStruct2))); 257 RETAILMSG(1,(L"size of (struct TstStruct3) = %d\n", sizeof(struct TstStruct3))); 258 RETAILMSG(1,(L"size of (struct TstStruct4) = %d\n", sizeof(struct TstStruct4))); 259 RETAILMSG(1,(L"size of (struct TstStruct5) = %d\n", sizeof(struct TstStruct5))); 260 RETAILMSG(1,(L"size of (struct TstStruct6) = %d\n", sizeof(struct TstStruct6))); 261 RETAILMSG(1,(L"size of (struct TstStruct6_R) = %d\n", sizeof(struct TstStruct6_R))); 262 RETAILMSG(1,(L"size of (struct TstStruct7) = %d\n", sizeof(struct TstStruct7))); 263 RETAILMSG(1,(L"size of (struct TstStruct8) = %d\n", sizeof(struct TstStruct8))); 264 RETAILMSG(1,(L"size of (struct TstStruct9) = %d\n", sizeof(struct TstStruct9))); 265 #else 266 printf("size of (struct TstStruct) = %d\n", sizeof(struct TstStruct)); 267 printf("size of (struct TstStruct2) = %d\n", sizeof(struct TstStruct2)); 268 printf("size of (struct TstStruct3) = %d\n", sizeof(struct TstStruct3)); 269 printf("size of (struct TstStruct4) = %d\n", sizeof(struct TstStruct4)); 270 printf("size of (struct TstStruct5) = %d\n", sizeof(struct TstStruct5)); 271 printf("size of (struct TstStruct6) = %d\n", sizeof(struct TstStruct6)); 272 printf("size of (struct TstStruct6_R) = %d\n", sizeof(struct TstStruct6_R)); 273 printf("size of (struct TstStruct7) = %d\n", sizeof(struct TstStruct7)); 274 printf("size of (struct TstStruct8) = %d\n", sizeof(struct TstStruct8)); 275 printf("size of (struct TstStruct9) = %d\n", sizeof(struct TstStruct9)); 276 #endif 277 }
// 在 WinCE 上运行输出如下: /* size of char is 1 size of short is 2 size of int is 4 size of long is 4 size of char * is 4 size of float is 4 size of double is 8 size of struct(char,char,int,char,char) is 12 size of struct(int,char,char,char,char) is 8 size of struct(int,char,char,char) is 8 size of struct(char,short) is 4 size of struct(char,TwoBytesEml(char,char)) is 3 size of struct(char,int) is 8 size of struct(char,FourBytesEml(char,char,char,char)) is 5 size of struct(char,double) is 16 size of struct(char,EightBytesEml(char,char,char,char,char,char,char,char)) is 9 size of (struct TstStruct) = 12 size of (struct TstStruct2) = 16 size of (struct TstStruct3) = 8 size of (struct TstStruct4) = 4 size of (struct TstStruct5) = 8 size of (struct TstStruct6) = 12 size of (struct TstStruct6_R) = 12 size of (struct TstStruct7) = 12 size of (struct TstStruct8) = 8 size of (struct TstStruct9) = 12 */
// 在 X86 上运行的输出如下: /* size of char is 1 size of short is 2 size of int is 4 size of long is 4 size of char * is 4 size of float is 4 size of double is 8 size of struct(char,char,int,char,char) is 12 size of struct(int,char,char,char,char) is 8 size of struct(int,char,char,char) is 8 size of struct(char,short) is 4 size of struct(char,TwoBytesEml(char,char)) is 3 size of struct(char,int) is 8 size of struct(char,FourBytesEml(char,char,char,char)) is 5 size of struct(char,double) is 16 size of struct(char,EightBytesEml(char,char,char,char,char,char,char,char)) is 9 size of (struct TstStruct) = 12 size of (struct TstStruct2) = 16 size of (struct TstStruct3) = 8 size of (struct TstStruct4) = 4 size of (struct TstStruct5) = 8 size of (struct TstStruct6) = 12 size of (struct TstStruct6_R) = 12 size of (struct TstStruct7) = 12 size of (struct TstStruct8) = 8 size of (struct TstStruct9) = 12 */