char a;
short b;
int c;
int d;
};
这个结构体的sizeof(test)=12,可以理解,内存对齐,char(1),short(2),int(4),对齐int为12。
大家再看下面两个结构体:
struct test1{
char a;
char e;
short b;
int c;
int d;
};
struct test2{
char a;
short b;
char e;
int c;
int d;
};
这时sizeof(test1)=12,而sizeof(test2)=16;
这就叫人困惑了,结构体test1中内存对齐两个char和short正好是4;而结构体test2中也是一样,按理说应该也是12,为什么就是16了?编译器到底怎么给结构体分配内存的?请高手指点!!
6 个解决方案
#1
单字节变量以单字节对齐,双字节变量以双字节对齐,四字节和以上长度变量以四字节对齐。
我一般就是这样理解的。
我一般就是这样理解的。
#2
a b 4
e 4
c 4
d 4
e 4
c 4
d 4
#3
这个由变量自身对齐值和指定对齐值中小的那个来决定。
a.数据类型自身的对齐值:
对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。
b.指定对齐值: #pragma pack (value)时的指定对齐值value。
1) 不是所有的系统都不支持字节对齐.
2) 编译器怎样设置字节对齐,不是所有平台都支持,X86是支持的,ARM编译器会出warnings.
#pragma pack(n) /* 其中n表示按n 字节对齐 */
#pragma pack() /* 取消指定对齐,恢复初始值 */
例如:
struct abc{
char c1, c2, c3;
short ui;
int i;
}
pack(1) sizeof(struct abc)=>9
pack(2) sizeof(struct abc)=>10
pack(4) sizeof(struct abc)=>12
3) 就算系统支持字节对齐访问,但是也不一定访问的数据就是正确的,这个看起来比较恐怖,看样子好像都没有问题,
真正到了Target Board上的时候就是不正确,基本上可能就是这个引起的。
例如:
int i=0x12345678;
char *p=NULL;
short *p1=NULL;
p = &i;
p1 = (short *)(p+1);
*p1 = 0x0000;
printf("p:%p\n", p);
printf("p1:%p\n", p1);
printf("i:%x\n", i);
#在Intel X86 平台上输出为:
p: 0xbfe70ce8
p1: 0xbfe70ce9
i: 120078
#而在 ARM上面却是:
p: 0x9220ff20
p1: 0x9220ff21
i: 12340000
从上面的结果中可以很明显的看出,ARM平台虽然支持字节对齐操作,但是到正确访问的时候却
是错误的。
4) 参考文章:
a) http://www.yuanma.org/data/2006/0723/article_1213.htm
b) http://www.devx.com/tips/Tip/13265
c) http://www.chinaitpower.com/2005September/2005-09-13/206312.html
d) http://www.chinaitpower.com/A/2003-01-03/45873.html
a.数据类型自身的对齐值:
对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。
b.指定对齐值: #pragma pack (value)时的指定对齐值value。
1) 不是所有的系统都不支持字节对齐.
2) 编译器怎样设置字节对齐,不是所有平台都支持,X86是支持的,ARM编译器会出warnings.
#pragma pack(n) /* 其中n表示按n 字节对齐 */
#pragma pack() /* 取消指定对齐,恢复初始值 */
例如:
struct abc{
char c1, c2, c3;
short ui;
int i;
}
pack(1) sizeof(struct abc)=>9
pack(2) sizeof(struct abc)=>10
pack(4) sizeof(struct abc)=>12
3) 就算系统支持字节对齐访问,但是也不一定访问的数据就是正确的,这个看起来比较恐怖,看样子好像都没有问题,
真正到了Target Board上的时候就是不正确,基本上可能就是这个引起的。
例如:
int i=0x12345678;
char *p=NULL;
short *p1=NULL;
p = &i;
p1 = (short *)(p+1);
*p1 = 0x0000;
printf("p:%p\n", p);
printf("p1:%p\n", p1);
printf("i:%x\n", i);
#在Intel X86 平台上输出为:
p: 0xbfe70ce8
p1: 0xbfe70ce9
i: 120078
#而在 ARM上面却是:
p: 0x9220ff20
p1: 0x9220ff21
i: 12340000
从上面的结果中可以很明显的看出,ARM平台虽然支持字节对齐操作,但是到正确访问的时候却
是错误的。
4) 参考文章:
a) http://www.yuanma.org/data/2006/0723/article_1213.htm
b) http://www.devx.com/tips/Tip/13265
c) http://www.chinaitpower.com/2005September/2005-09-13/206312.html
d) http://www.chinaitpower.com/A/2003-01-03/45873.html
#4
test1:---- ---- ---- ----
aebb cccc dddd (12)
test2:---- ---- ---- ----
a bb e cccc dddd (16)
空格表示不存储变量这样清楚点吗?
aebb cccc dddd (12)
test2:---- ---- ---- ----
a bb e cccc dddd (16)
空格表示不存储变量这样清楚点吗?
#5
多谢各位大虾指点!
但你们说的我都知道,还是没有回答我的问题为什么会是这样?
但你们说的我都知道,还是没有回答我的问题为什么会是这样?
#6
内存访问问题,大多数编译器默认为内存单元是4字节,因为这个时候内存访问效率最好,
所以一般都是以4字节对齐的。(不知道错了没有。。:))
所以一般都是以4字节对齐的。(不知道错了没有。。:))
#1
单字节变量以单字节对齐,双字节变量以双字节对齐,四字节和以上长度变量以四字节对齐。
我一般就是这样理解的。
我一般就是这样理解的。
#2
a b 4
e 4
c 4
d 4
e 4
c 4
d 4
#3
这个由变量自身对齐值和指定对齐值中小的那个来决定。
a.数据类型自身的对齐值:
对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。
b.指定对齐值: #pragma pack (value)时的指定对齐值value。
1) 不是所有的系统都不支持字节对齐.
2) 编译器怎样设置字节对齐,不是所有平台都支持,X86是支持的,ARM编译器会出warnings.
#pragma pack(n) /* 其中n表示按n 字节对齐 */
#pragma pack() /* 取消指定对齐,恢复初始值 */
例如:
struct abc{
char c1, c2, c3;
short ui;
int i;
}
pack(1) sizeof(struct abc)=>9
pack(2) sizeof(struct abc)=>10
pack(4) sizeof(struct abc)=>12
3) 就算系统支持字节对齐访问,但是也不一定访问的数据就是正确的,这个看起来比较恐怖,看样子好像都没有问题,
真正到了Target Board上的时候就是不正确,基本上可能就是这个引起的。
例如:
int i=0x12345678;
char *p=NULL;
short *p1=NULL;
p = &i;
p1 = (short *)(p+1);
*p1 = 0x0000;
printf("p:%p\n", p);
printf("p1:%p\n", p1);
printf("i:%x\n", i);
#在Intel X86 平台上输出为:
p: 0xbfe70ce8
p1: 0xbfe70ce9
i: 120078
#而在 ARM上面却是:
p: 0x9220ff20
p1: 0x9220ff21
i: 12340000
从上面的结果中可以很明显的看出,ARM平台虽然支持字节对齐操作,但是到正确访问的时候却
是错误的。
4) 参考文章:
a) http://www.yuanma.org/data/2006/0723/article_1213.htm
b) http://www.devx.com/tips/Tip/13265
c) http://www.chinaitpower.com/2005September/2005-09-13/206312.html
d) http://www.chinaitpower.com/A/2003-01-03/45873.html
a.数据类型自身的对齐值:
对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。
b.指定对齐值: #pragma pack (value)时的指定对齐值value。
1) 不是所有的系统都不支持字节对齐.
2) 编译器怎样设置字节对齐,不是所有平台都支持,X86是支持的,ARM编译器会出warnings.
#pragma pack(n) /* 其中n表示按n 字节对齐 */
#pragma pack() /* 取消指定对齐,恢复初始值 */
例如:
struct abc{
char c1, c2, c3;
short ui;
int i;
}
pack(1) sizeof(struct abc)=>9
pack(2) sizeof(struct abc)=>10
pack(4) sizeof(struct abc)=>12
3) 就算系统支持字节对齐访问,但是也不一定访问的数据就是正确的,这个看起来比较恐怖,看样子好像都没有问题,
真正到了Target Board上的时候就是不正确,基本上可能就是这个引起的。
例如:
int i=0x12345678;
char *p=NULL;
short *p1=NULL;
p = &i;
p1 = (short *)(p+1);
*p1 = 0x0000;
printf("p:%p\n", p);
printf("p1:%p\n", p1);
printf("i:%x\n", i);
#在Intel X86 平台上输出为:
p: 0xbfe70ce8
p1: 0xbfe70ce9
i: 120078
#而在 ARM上面却是:
p: 0x9220ff20
p1: 0x9220ff21
i: 12340000
从上面的结果中可以很明显的看出,ARM平台虽然支持字节对齐操作,但是到正确访问的时候却
是错误的。
4) 参考文章:
a) http://www.yuanma.org/data/2006/0723/article_1213.htm
b) http://www.devx.com/tips/Tip/13265
c) http://www.chinaitpower.com/2005September/2005-09-13/206312.html
d) http://www.chinaitpower.com/A/2003-01-03/45873.html
#4
test1:---- ---- ---- ----
aebb cccc dddd (12)
test2:---- ---- ---- ----
a bb e cccc dddd (16)
空格表示不存储变量这样清楚点吗?
aebb cccc dddd (12)
test2:---- ---- ---- ----
a bb e cccc dddd (16)
空格表示不存储变量这样清楚点吗?
#5
多谢各位大虾指点!
但你们说的我都知道,还是没有回答我的问题为什么会是这样?
但你们说的我都知道,还是没有回答我的问题为什么会是这样?
#6
内存访问问题,大多数编译器默认为内存单元是4字节,因为这个时候内存访问效率最好,
所以一般都是以4字节对齐的。(不知道错了没有。。:))
所以一般都是以4字节对齐的。(不知道错了没有。。:))