`

与结构体对齐有关的 分析内存分配的笔试题

 
阅读更多

 

 参考 : http://www.jianshu.com/p/b1fcb6c73b28      http://blog.csdn.net/mbh_1991/article/details/10241785

 

其实 , 我想找的工作是与Java相关的,可是每次做的几乎都是c/c++的题目 == ;

 

 第一道题 :

  输出什么 ?

#include<stdio.h>

struct A
{
    unsigned char x;
    unsigned char y;
    int z;
};

int main(){
    struct A a;
    printf("%d,%d,%d,%d",sizeof(a));
    return 0;
}

 输出的是 : 拷贝代码 试试, or.....

 这道题目中,怎么求sizeof(a) , 即a所占的字节大小!

 一般的我们,可能就会字节根据每个基本数据类型的字节大小,相加就得到了,比如这里,1+1+4 , 可是真的这么简单吗?

99%的不可能,这里牵扯到的就是结构体的对齐问题;

那么什么是结构体的对齐?

 看下面这个图 :  这三个元素都是位于同一个结构体中,倘若没有对齐的话,如果我们想访问第二个short元素,由于中间夹杂了别的元素

 访问效率降低,而当进行了对齐处理后,每个元素都按照相应的参数对齐,比如这里是2,按照2对齐,访问第二个short的时候,直接访问第5个地址就可以了。

 

  对齐的准则:

 

   a.第一个成员起始于0偏移处
    b.每个成员按其类型大小和指定对齐参数n中较小的一个进行对齐 // n = min(max(结构体中数据类型) , #pragma pack(n))
   c.结构体总长度必须为所有对齐参数的整数倍
    d.对于数组,可以拆开看做n个数组元素

 回到上面的题目 , 结构体所占字节最大的数据类型为int (4) , prama pack(n) 后面那道题会有, 默认会是8; 所以 对齐参数 = min(4,8) = 4

 所以,我们可以得到该结构体在内存中的分布 ; x , (0 , 1)  y (1 ,2)  z (4,8) 如果不对齐处理的话,那么z的地址空间就会(2,6);

 所以,该结构题所占的内存空间为8字节!

 

第二道题 :

#include<stdio.h>
#include<stdint.h>
#pragma pack(8)
//struct X{  //第一种
//    uint8_t a; // unsigned char  1
//    uint32_t b; // unsigned int  4
//    uint16_t c; // unsigned short int 2
//};
struct X{ // 第二种
    uint8_t a;
    uint16_t c;
    uint32_t b;
};
#pragma pack()

int main(){
    struct X x;
    printf("%p\n" , x.a);
    printf("%p\n" , x.b);
    printf("%p\n" , x.c);
    printf("%d\n",sizeof(x));
    return 0;
}

  如果按照第一种的方式构建结构体,

  n  = min(4, 8) = 4

  内存分布 : a (0,1) , b(4,8) , c (8 ,10 )     (1, 4) and  (10 , 12)  填充 , 所以 size = 12字节

  如果按第二种方式 ;

  因为a  c 可以放在一个(0 , 4) 里面, 所以,size = 8字节

  看图 :

 

拓展一下 :

 

#include <stdio.h>  
  
#pragma pack(8)  
//#pragma pack(4)  
struct S1  
{  
    short a;  
    int  b;  
};  
  
struct S2  
{  
    char c;  
    struct S1 d;  // 在这个结构体中引用了另一个结构体 , 如果对齐
    double e;  
};  
  
#pragma pack()  
  
int main()  
{  
    struct S2 s2;  
      
    printf("%d\n", sizeof(struct S1));  
    printf("%d\n", sizeof(struct S2));   
  
    return 0;  
}  

   在这个结构体中引用了另一个结构体 , 如果对齐参数为4, 那么在结构体s2中, char 类型 可以 与 结构体s1中的short合并?
   运行一下就知道了;

   答案是不会的,当 #pragma pack(4)是,即对齐参数=4 , s1的size= 4 , s2的size = 4 + 8 + 4 + 4 = 20 double = 8字节

   看图 :  看到了 1 那个地方是不会合并的

     

如果对齐参数是8字节,同理可得到 , size= 24 ;

 

 

  

分享到:
评论

相关推荐

    C++面试题之结构体内存对齐计算问题总结大全

    本文给大家介绍的是关于C++结构体内存对齐计算的相关内容,内存对齐计算可谓是笔试题的必考题,但是如何按照计算原则算出正确答案一开始也不是很容易的事,所以专门通过例子来复习下关于结构体内存对齐的计算问题。...

    免费下载:C语言难点分析整理.doc

    54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法的思路 283 57. 重新认识:指向函数的指针 288 58. 链表的源码 291 59. 高质量的子程序 295 60. 高级C语言程序员测试必过的十六道最佳题目+...

    c语言难点分析整理,C语言

    54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法的思路 283 57. 重新认识:指向函数的指针 288 58. 链表的源码 291 59. 高质量的子程序 295 60. 高级C语言程序员测试必过的十六道最佳题目+...

    C语言难点分析整理.doc

    54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法的思路 283 57. 重新认识:指向函数的指针 288 58. 链表的源码 291 59. 高质量的子程序 295 60. 高级C语言程序员测试必过的十六道最佳...

    C语言难点分析整理

    54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法的思路 283 57. 重新认识:指向函数的指针 288 58. 链表的源码 291 59. 高质量的子程序 295 60. 高级C语言程序员测试必过的十六道最佳题目+...

    高级进阶c语言教程..doc

    54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法的思路 283 57. 重新认识:指向函数的指针 288 58. 链表的源码 291 59. 高质量的子程序 295 60. 高级C语言程序员测试必过的十六道最佳题目+...

    高级C语言 C 语言编程要点

    54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法的思路 283 57. 重新认识:指向函数的指针 288 58. 链表的源码 291 59. 高质量的子程序 295 60. 高级C语言程序员测试必过的十六道最佳题目+...

    史上最强的C语言资料

    54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法的思路 283 57. 重新认识:指向函数的指针 288 58. 链表的源码 291 59. 高质量的子程序 295 60. 高级C语言程序员测试必过的十六道最佳题目+...

    高级C语言详解

    54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法的思路 283 57. 重新认识:指向函数的指针 288 58. 链表的源码 291 59. 高质量的子程序 295 60. 高级C语言程序员测试必过的十六道最佳题目+...

    C学习深入学习总结

    C语言各种常用关键字详细解释学习,都是总结面试,都是比较好的笔试题。 1 变量 3 1.1 全局变量,局部变量,,常量分别保存在内存中的什么地方? 3 1.2 不同类型的变量,你是否知道其作用域? 3 1.3 全局变量和局部...

    C语言/C++常见笔试面试题难疑点汇总

    用来改变编译器的字节对齐方式。 #pragma code_seg。它能够设置程序中的函数在obj文件中所在的代码段。如果未指定参数,函数将放置在默认代码段.text中 #pragma once。保证所在文件只会被包含一次,它是基于磁盘文件...

    C 语言深度解剖--解开程序员面试笔试的秘密

    1.11.2,节省空间,避免不必要的内存分配,同时提高效率.................................... 35 1.12,最易变的关键字----volatile..........................................................................

    高级C语言.PDF

    1. C 语言中的指针和内存泄漏 ............................................................................................................. 5 2. C语言难点分析整理 ..........................................

Global site tag (gtag.js) - Google Analytics