下面继续验证我的说法,编译器给结构体分配内存是,直接分配所含成员中,数据类型最大那个的占用字节数乘以元素个数。
这张图片验证了,结构体可以分配1个字节,而结构体成员里面就一个char型变量,字节数最大占用为1。
看了这么多,下面来个题目。
struct a
{
char a0;
char b;
int a1;
}ma;
char a2,a3,a4;
int* a5;
int main()
{
a2 = sizeof(ma);
a3 = sizeof(char);
a4 = sizeof(int);
a5 = &ma.a1;
}
设ma地址0x2000002c,请问,a2、a3、a4、a5的值各为多少?
嘿嘿,是8,就是说,如果是连续的char型变量,编译器依旧会给它分配两个字节的内存空间。
把上题目改一下哈
struct a
{
char a0;
int a1;
char b;
}ma;
char a2,a3,a4;
int* a5;
int main()
{
a2 = sizeof(ma);
a3 = sizeof(char);
a4 = sizeof(int);
a5 = &ma.a1;
}
设ma地址为0x2000010c,请问,a2、a3、a4、a5的值各为多少?
这次的内存地址分配变更了,map文件如下
a2 0x2000002c Data 1 main.o(.data)
a3 0x2000002d Data 1 main.o(.data)
a4 0x2000002e Data 1 main.o(.data)
a5 0x20000030 Data 4 main.o(.data)
__stdout 0x20000038 Data 4 stdout.o(.data)
Uart 0x2000003c Data 208 main.o(.bss)
ma 0x2000010c Data 12 main.o(.bss)
从上面的仿真分析,ma.a0依旧是占用4个内存字节,ma.b也是4个。
为了使验证更使人信服,我增加了两个测试,增加位定义。
如图,即使我只声明了一个位,依旧分配了4个字节。
*.map文件中的地址分配如下
ma 0x2000002c Data 2 main.o(.data)
a2 0x2000002e Data 1 main.o(.data)
a3 0x2000002f Data 1 main.o(.data)
a4 0x20000030 Data 1 main.o(.data)
a5 0x20000034 Data 4 main.o(.data)
就是说,如果连续定义8个位,只占用了两个字节
综上所述,如果可能的话,在编写c语言的时候,尽量将数据类型相同的变量连续排在一起。
写完了,看懂了吗,不懂?我就喜欢你懵逼的样子,<( ̄︶ ̄)> 。
|