Record and Summarize

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

结构体在内存中的存储形式

  1. 先说明一下,以下的情况,默认结构体初始地址是0,我猜编译器默认也是这么做的。否则sizeof(类型)就无法判定了(注意括号里是类型,不是变量)。
  2. 同时,本文中所说的不仅适用于结构体,例如共用体也是按照本文所说的进行内存分配,不过要比结构体简单得多。
  3. 以下是两条原则:
    1. 原则一:结构体中元素是按照定义顺序一个一个放到内存中去的,但并不是紧密排列的。从结构体存储的首地址开始,每一个元素放置到内存中时,它都会认为内存是以它自己的大小来划分的,因此元素放置的位置一定会在自己宽度的整数倍上开始。
    2. 原则二:在经过第一原则分析后,检查计算出的存储单元是否为所有元素中最宽的元素的长度的整数倍,是,则结束;若不是,则补齐为它的整数倍。
  4. 补充一个概念——对齐系数:每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pargma pack(n),n =1,2,4,8,16,...,2m来改变这一系数,其中n就是对齐系数。也可以通过#pragma pack (),取消自定义字节对齐方式。因此,上面提到的两条原则在实际情况下需要做一些改变,引入对齐系数。改变如下:
    1. 原则一:结构体中元素是按照定义顺序一个一个放到内存中去的,但并不是紧密排列的。从结构体存储的首地址开始,若一个元素的大小小于等于对齐系数,当这个元素被放置到内存中时,它会认为内存是以它自己的大小来划分的,因此元素放置的位置一定会在自己宽度的整数倍上开始。若一个元素的大小大于对齐系数,当这个元素被放置到内存中时,它会认为内存是以对齐系数划分的,因此元素放置的位置一定会在对齐系数整数倍上开始。
    2. 原则二:在经过第一原则分析后,则检查所有元素中最宽的元素的大小,若大于对齐系数,检查计算出的存储单元是否为对齐系数的整数倍;否则检查计算出的存储单元是否为所有元素中最宽的元素的长度的整数倍,是,则结束;若不是,则补齐为它的整数倍。
  5. 注:对于结构体中含有复杂类型(如结构体)变量,则该复杂类型变量被放置的位置就是它的所有成员使用的对齐参数中最大的一个的倍数,而该复杂变量的大小不会改变。
  6. 注:对于数组,可以看作多个同类型的变量。
  7. 注:在linux下,gcc的默认对齐系数是4,并且不能把默认系数设置成为大于4的数,设置成为1或2还是有效的。
posted on 2013-12-29 22:42  zhangjing327  阅读(985)  评论(0编辑  收藏  举报