• C语言结构体的存储空间分配


    一. 结构体在内存中是如何实际存储的呢?

    1.如果某个机器的整型值长度为4个字节,那么结构体的起始存储位置必须能被4整除

    2.编译器按照成员列表的顺序一个接一个地给每个成员分配内存。其中对于各个成员,编译器根据其类型分配赋予对其要求,比如char成员,按地址能被1整除对齐;short成员,按地址能被2整除对齐;int成员,按地址能被4整除对齐......

    3.编译器在存储结构体成员时,为了满足各个成员的正确边界对齐要求,会在成员之间添加用于填充的额外内存空间。

    4.举个例子:

    1. struct test {
    2. char a;
    3. int b;
    4. char c;
    5. }

    内存布局如下:

    二. 结构体成员重排与节约内存

    有时,我们有充分的理由,决定不对结构体的成员进行重排以减少因对齐带来的空间损失。例如,我们可能想把相关的结构成员存储在一起,提高程序的可维护性和可读性。但是,如果不存在这样的理由,结构的成员应该根据他们的边界需要进行排列,减少因边界对齐而造成的内存损失。

    特别的,在某些情况下,我们必须按照严格的边界对齐要求来定义结构体以获取正确的数据,比如:考虑解析BMP图片的代码例子。

    RGB24(RGB888)生成BMP图片代码_denglin12315的博客-CSDN博客

     关于header的定义1(包括3个部分):

    1. 1. 2字节的字符
    2. 2. BITMAPFILEHEADER部分
    3. typedef struct /**** BMP file header structure ****/
    4. {
    5. unsigned int bfSize; /* Size of file */
    6. unsigned short bfReserved1; /* Reserved */
    7. unsigned short bfReserved2; /* ... */
    8. unsigned int bfOffBits; /* Offset to bitmap data */
    9. } BITMAPFILEHEADER1;
    10. 3.BITMAPINFOHEADER部分
    11. typedef struct /**** BMP file info structure ****/
    12. {
    13. unsigned int biSize; /* Size of info header */
    14. int biWidth; /* Width of image */
    15. int biHeight; /* Height of image */
    16. unsigned short biPlanes; /* Number of color planes */
    17. unsigned short biBitCount; /* Number of bits per pixel */
    18. unsigned int biCompression; /* Type of compression to use */
    19. unsigned int biSizeImage; /* Size of image data */
    20. int biXPelsPerMeter; /* X pixels per meter */
    21. int biYPelsPerMeter; /* Y pixels per meter */
    22. unsigned int biClrUsed; /* Number of colors used */
    23. unsigned int biClrImportant; /* Number of important colors */
    24. } BITMAPINFOHEADER1;

     关于header的定义2:

    1. typedef struct /**** BMP file info structure ****/
    2. {
    3. char simbol[2]
    4. unsigned int bfSize; /* Size of file */
    5. unsigned short bfReserved1; /* Reserved */
    6. unsigned short bfReserved2; /* ... */
    7. unsigned int bfOffBits; /* Offset to bitmap data */
    8. unsigned int biSize; /* Size of info header */
    9. int biWidth; /* Width of image */
    10. int biHeight; /* Height of image */
    11. unsigned short biPlanes; /* Number of color planes */
    12. unsigned short biBitCount; /* Number of bits per pixel */
    13. unsigned int biCompression; /* Type of compression to use */
    14. unsigned int biSizeImage; /* Size of image data */
    15. int biXPelsPerMeter; /* X pixels per meter */
    16. int biYPelsPerMeter; /* Y pixels per meter */
    17. unsigned int biClrUsed; /* Number of colors used */
    18. unsigned int biClrImportant; /* Number of important colors */
    19. } BITMAPINFOHEADER2;

    这里直接说答案并提问: 为什么不能按照定义2的方式,而非要按照按照定义1的方式?定义2不是更简单直观吗?

    答案提示:比较一下 2 + sizeof(BITMAPFILEHEADER1) + sizeof(BITMAPINFOHEADER1) 与

    sizeof(BITMAPINFOHEADER2)的大小,标准bmp文件头的大小应该是和2 + sizeof(BITMAPFILEHEADER1) + sizeof(BITMAPINFOHEADER1)的值相等。出现以上差异的原因就是结构体对齐机制导致的。

    三. 结构体相关的宏

    1.sizeof()

    2.offsetof(type, member)    ———  定义于stddef.h文件

  • 相关阅读:
    react面试题总结一波,以备不时之需
    动规(21)-并查集基础题——搭配购买
    15:00面试,15:08就出来了,问的问题有点变态。。。
    数据库的级联删除
    03-背景属性
    语音识别芯片NRK3301在智能茶吧机的应用
    【工作规划】未来自我学习计划及发展注意事项
    百度SEO优化(提升网站排名的秘诀)
    [go]配置文件(CSV与YAML)读写
    【LMKD】十 有问有答 - FAQ
  • 原文地址:https://blog.csdn.net/denglin12315/article/details/126704679