内存对齐相关面试题
2018-01-14 20:21
169 查看
题目一
#pragma pack (4) unsigned short* pucchararray[10][10]; typedef union unRec { unsigned long L1; unsigned short S2[7]; unsigned char C3; }REC_S; REC_S stmax, *pstmax; int main() { printf("%d\n", sizeof(pucchararray)); printf("%d\n", sizeof(stmax)); printf("%d\n", sizeof(pstmax)); printf("%d\n", sizeof(*pstmax)); system("pause"); return 0; }
首先题目是考察联合体的内存对齐,联合体的内存存放是共用一段连续的内存空间。所以联合体的大小至少得是最大成员的大小,由于内存对齐所以联合体的大小必须是最大对齐数的整数倍。
本题中第一个指针数组,是一个10*10大小的数组每一个元素都是指针,所以是400.
第二个stmax是一个结构体变量,所以他的大小就是结构体的大小即16.
第三个pstmax是一个结构体指针,为4个字节大小。
第四个*pstmax,对该结构体指针解引用,得到该结构体的大小,16.
题目二
3.struct BBB { long A1; char A2; char A3; long A4; long A5; }*p; int main() { p = (struct BBB*)0x100000; printf("%d\n", sizeof(struct BBB)); printf("%#x\n", p + 0x1); printf("%#x\n",(unsigned long) p + 0x1); printf("%#x\n",(unsigned long *) p + 0x1); printf("%#x\n", (char *)p + 0x1); system("pause"); return 0; }
本题目考察了结构体的内存对齐及对指针的运算(默认4字节对齐)。首先先求出该结构体的大小。
默认第一个变量对齐,占4字节,第二三个变量可以直接存放,各占1字节,第四个变量要偏移到偏移量为8处,占4字节,第五个变量此时已对齐,占4字节。此时该结构体大小为16,并且结构体大小要是最大对齐数的整数倍,即是4的整数倍,仍是16.
所以该题目中设置了一个结构体指针,并将该指针的指向改为0x100000.
p + 0x1:对指针+1,是加上其指向类型的大小,所以加16,16进制表示为:0x1000010.
(unsigned long) p + 0x1:将指针强转为无符号长整形,对其加1,就是+1,即0x100001.
(unsigned long *) p + 0x1:将指针强转为无符号整形指针类型,对指针加1,仍然是加上其所指向类型的大小,long的大小4,即0x100004.
(char *)p + 0x1:将指针强转为字符指针类型,对指针加1,加上其所指类型的大小,就是1,即0x100001.
结果如图所示:
题目三
struct AAA { //位段不用对齐 unsigned char c1 : 1; unsigned char c2 : 2; unsigned char c3 : 6; unsigned char c4 : 4; unsigned char c5; unsigned char c6 : 4; unsigned char c7; }; int main() { printf("%d\n", sizeof(struct AAA)); system("pause"); return 0; }
位段在内存中的存储是按照比特位存储,当该申请类型的上一个字节的比特位够存时可以直接存入,不够时就要重新开辟新的字节。并且,最值得注意的一点,位段不需要对齐。
这道题目用一张图可以来说明他的内存存储。
题目四
int main() { unsigned char uc[4]; struct PIM { unsigned char c1; unsigned char data0 : 1; unsigned char data1 : 2; unsigned char data2 : 3; }*pst; pst = (struct PIM*)uc; memset(uc, 0, 4); pst->c1 = 2; pst->data0 = 3; pst->data1 = 4; pst->data2 = 5; printf("%02x %02x %02x %02x", uc[0], uc[1], uc[2], uc[3]); system("pause"); return 0; }
本题仍然考察了位段,位段都是按照比特位存储的,所以在赋值是也是按照比特位赋值。
用下图来解释:
所以答案为:02 29 00 00
题目五
#pragma pack(4) union AAA { struct { char c1; short s1; char c2; }half; short s2; }number; struct BBB { char c1; short s1; char c2; short s2; }half; struct CCC { struct { char c1; short s1; char c2; }half; long l1; }; int main() { printf("%d\n", sizeof(union AAA)); printf("%d\n", sizeof(struct BBB)); printf("%d\n", sizeof(struct CCC)); system("pause"); return 0; }
本题考查了联合体与结构体的内存对齐,以及结构体嵌套结构体的情况下,结构体的内存对齐。
结果如下图所示:
在做有关于内存对齐的题目时,首先要判别清楚是结构体联合体还是位段,因为结构体和联合体需要对齐,位段不需要对齐。并且他们的存储也各有不同,分别的规则要熟记并熟练,遇到问题时,一步一步分析清楚就好了。
相关文章推荐
- 接口和抽象类相关面试题
- JAVA相关面试题
- python相关面试题
- 二叉树相关面试题
- C++ const面试题和相关的解释
- Servlet与JSP 相关面试题
- Python工程师面试题 与Python Web相关
- 单链表及相关面试题
- 面试题5: 链表的相关操作
- 前端面试总结---CSS相关面试题
- 转载:Eclipse 相关技术面试题
- 链表相关面试题(zz)
- 面试题——日历相关
- Hadoop相关面试题(一)
- Python工程师面试题 与Python基础语法相关
- 链表相关面试题(基础篇)
- 【面试题】c++有哪四个类型转换相关的关键字?
- TCP相关面试题总结
- 一个String相关的面试题
- 关于线程相关的一些理解和常见面试题