May
18
本来面试前应该看的:字节对齐, #pragma pack
网上可以搜到很多相关的资料,这里不具体说了,
大致就是,定义struct/class的时候 编译器会把其中的每个成员的存储位置对齐
对齐原则一般是和该成员大小一致,比如int的就从%4=0的地址开始存储,多余的空间就编译器随便填充了。
然后struct还要填充,直到整个struct的大小是最大成员大小的倍数(VC6.0)——为什么呢?
Felix觉得这样是为了保证连续存储的时候下一个struct的最大成员也是对齐的。
此外,编译器还会对struct的存储地址进行对齐。
我实际测试了一下,我发现32bit的gcc在对struct进行填充的时候
如果某成员的大小大于4Bytes(long long, double)的时候,实际上是以4字节对齐的。
如果在程序中指定了
#pragma pack(n)
那么对齐的时候就会把元素的大小和n进行比较,取较小的那个来对齐。
此外:
#pragma pack(push)
#program pack(pop)
可以成对使用,用来保存(push)当前的n和取出(pop)之前的n——当然,这是在编译过程中处理的。
下面是我的一段测试程序:
转载请注明出自 ,如是转载文则注明原出处,谢谢:)
RSS订阅地址: https://www.felix021.com/blog/feed.php 。
大致就是,定义struct/class的时候 编译器会把其中的每个成员的存储位置对齐
对齐原则一般是和该成员大小一致,比如int的就从%4=0的地址开始存储,多余的空间就编译器随便填充了。
然后struct还要填充,直到整个struct的大小是最大成员大小的倍数(VC6.0)——为什么呢?
Felix觉得这样是为了保证连续存储的时候下一个struct的最大成员也是对齐的。
此外,编译器还会对struct的存储地址进行对齐。
我实际测试了一下,我发现32bit的gcc在对struct进行填充的时候
如果某成员的大小大于4Bytes(long long, double)的时候,实际上是以4字节对齐的。
如果在程序中指定了
#pragma pack(n)
那么对齐的时候就会把元素的大小和n进行比较,取较小的那个来对齐。
此外:
#pragma pack(push)
#program pack(pop)
可以成对使用,用来保存(push)当前的n和取出(pop)之前的n——当然,这是在编译过程中处理的。
下面是我的一段测试程序:
#include <stdio.h>
#include <string.h>
struct ta{
unsigned char a; // 1 Byte
unsigned long long b; // 8 Byte
unsigned short c; // 1 Byte
};
#pragma pack(2)
struct tb{
unsigned char a; // 1 Byte
unsigned long long b; // 8 Byte
unsigned short c; // 1 Byte
};
void dump(void *t, int size){
printf("---- @%x size = %2d ----\n", (int)t, size);
for (int i = 0; i < size; ++i){
printf("%2d: %x\n", i, *((char*)t+i));
}
printf("-------------------\n");
}
int main(){
ta a;
memset(&a, 0, sizeof(ta));
a.a = 0xff;
a.b = 0xffffffffffffffffull;
a.c = 0xffff;
dump(&a, sizeof(ta));
tb b;
memset(&b, 0, sizeof(tb));
b.a = 0xff;
b.b = 0xffffffffffffffffull;
b.c = 0xffff;
dump(&b, sizeof(tb));
return 0;
}
#include <string.h>
struct ta{
unsigned char a; // 1 Byte
unsigned long long b; // 8 Byte
unsigned short c; // 1 Byte
};
#pragma pack(2)
struct tb{
unsigned char a; // 1 Byte
unsigned long long b; // 8 Byte
unsigned short c; // 1 Byte
};
void dump(void *t, int size){
printf("---- @%x size = %2d ----\n", (int)t, size);
for (int i = 0; i < size; ++i){
printf("%2d: %x\n", i, *((char*)t+i));
}
printf("-------------------\n");
}
int main(){
ta a;
memset(&a, 0, sizeof(ta));
a.a = 0xff;
a.b = 0xffffffffffffffffull;
a.c = 0xffff;
dump(&a, sizeof(ta));
tb b;
memset(&b, 0, sizeof(tb));
b.a = 0xff;
b.b = 0xffffffffffffffffull;
b.c = 0xffff;
dump(&b, sizeof(tb));
return 0;
}
欢迎扫码关注:
转载请注明出自 ,如是转载文则注明原出处,谢谢:)
RSS订阅地址: https://www.felix021.com/blog/feed.php 。
非人
2009-5-18 20:08
呵呵 我倒是准备这个了 结果那人没问 汗- -
felix021 回复于 2009-5-19 13:56
。。。
分页: 1/1 1