SIZEOF()计算结构体的问题;

来源:互联网 发布:全国信鸽成绩查询软件 编辑:程序博客网 时间:2024/05/21 06:31

下面这样的一个结构体:
struct stu1
          {
                int i;
                char c;
                int j;
          };
先介绍一个相关的概念——偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址的差。结构体大小等于最后一个成
员的偏移量加上最后一个成员的大
小。显然,结构体变量中第一个成员的地址就是结构体变量的首地址。因此,第一个成员i的偏移量为0。第二个成员c的偏移量是第一个成员的偏移量加上第一个
成员的大小(0+4),其值为4;第三个成员j的偏移量是第二个成员的偏移量加上第二个成员的大小(4+1),其值为5。
实际上,由于存储变量时地址对齐的要求,编译器在编译程序时会遵循两条原则:一、结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍) 二、结构体大小必须是所有成员大小的整数倍,也就是必须为最占内存成员数据类型大小的整数倍;
对照第一条,上面的例子中前两个成员的偏移量都满足要求,但第三个成员的偏移量为5,并不是自身(int)大小的整数倍。编译器在处理时会在第二个成员后面补上3个空字节,使得第三个成员的偏移量变成8。
对照第二条,结构体大小等于最后一个成员的偏移量加上其大小,上面的例子中计算出来的大小为12,满足要求。

如下结构体定义:

typedef struct tagItemData
{
 unsigned char uNo;【1】
 unsigned char uConnectState; //uConnectState = 1 means connect targe board other else【2】
 unsigned char downMod; //0x00 == ETH 0x01 == RS530 0x02 == E1【3】
 unsigned char uEthRateMod; //0x00 = 10M/ 0x01 = 100M  【4】
 //wo do not mind the data stream
 unsigned char uClkSel[2];【6】
 unsigned char uRateData[2];【8】
 unsigned char uRateNo[2]; 【10】
 unsigned char szExtClk[2][10];【30】
 unsigned short uDelayTime[2];【34+2=36%sizeof(long)==0】
 long lThreshHold[2]; //do not down perr actually【44】
 unsigned char uBrustMod[2];【46】
 unsigned char uBrustLen[2];【48】
 unsigned char uIntTime[2];// channel Int Time UNIT is 10s
 //add additional items for test
 char uBer[2][3];【54】
 unsigned char uEdge[2];【56+4=60%4=0】//总体内存必须保证为最大数据类型所占内存的N倍;(N为正整数);

}ITEMDATA,*PITEMDATA;

可以得出sizeof(ITEMDATA)=60;

 

验证结构体关于字对齐的存储方式:

方法:将结构体内容完全复制到堆中,将堆中数据一一输出;

代码如下:

#include"stdio.h"
#include"stdlib.h"
#include"memory.h"
typedef struct tagTest
{
 char a;
 char b;
 int c;
}TEST,*PTEST;//由于字对齐,所占内存为8BYTES;

void main()
{
  TEST _test={0x01,0x02,0x01020304};
  PTEST _ptest=(PTEST)(&_test);
  void* _pvoid;

  _pvoid=malloc(sizeof(TEST));
  memset(_pvoid,0x00,sizeof(TEST));
  memcpy((void*)_pvoid,(void*)_ptest,sizeof(TEST));
  char* _pchar=(char*)_pvoid;
  for(int i=0;i<sizeof(TEST);i++)
  printf("%d\n",*(_pchar+i));
}

输出结果:

1

1

-52

-52

4

3

2

1

press anykey to continue

 

两个-52即为为满足字对齐条件而补齐在char b;后的2个空字节;

 

原创粉丝点击