计算结构体大小

char类型的长度被定义为一个8位字节,这很简单。

short类型的长度至少为两字节。在有些计算机上,对于有些编译程序,short类型的长度可能为4字节,或者更长。

int类型是一个整数的“自然”大小,其长度至少为两字节,并且至少要和short类型一样长。在16位计算机上,int类型的长度可能为两字节;在32位计算机上,可能为4字节;当64位计算机流行起来后,int类型的长度可能会达到8字节。这里说的都是“可能”,例如,早期的Motorala 68000是一种16/32位的混合型计算机,依赖于不同的命令行选项,一个68000编译程序能产生两字节长或4字节长的int类型。

long类型至少和int类型一样长(因此,它也至少和short类型一样长)。long类型的长度至少为4字节。32位计算机上的编译程序可能会使short,int和long类型的长度都为4字节——也可能不会。

结构体中的成员可以是不同的数据类型,成员按照定义时的顺序依次存储在连续的内存空间。和数组不一样的是,结构体的大小不是所有成员大小简单的相加,需要考虑到系统在存储结构体变量时的地址对齐问题。 
        通过下面这个计算结构体大小的示例来理解与学习如何计算结构体的大小。 
struct stu 

       int i; 
       char c; 
       int j; 
}; 
        首先介绍一个相关的概念——偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址的差。然后给出结构体大小的定义:结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。显然,结构体变量中第一个成员的地址就是结构体变量的首地址。因此,第一个成员i的偏移量为0。第二个成员c的偏移量是第一个成员的偏移量加上第一个成员的大小(0+4),其值为4;第三个成员j的偏移量是第二个成员的偏移量加上第二个成员的大小(4+1),其值为5。 
        实际上,由于存储变量时地址对齐的要求,编译器在编译程序时会遵循三条原则: 
一、结构体变量中成员的偏移量必须是该成员大小的整数倍(0被认为是任何数的整数倍) 。 
二、结构体大小必须是所有成员大小的整数倍。

三、如果结构体中的成员又是另外一种结构体,只需把其展开即可。但有一点需要注意,展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。

注:以上三条原则仅适用于VC,gcc关于内存对齐有不同的机制。

对照第一条,上面的例子中前两个成员的偏移量都满足要求,但第三个成员的偏移量为5,并不是自身(int)大小的整数倍。编译器在处理时会在第二个成员后面补上3个空字节,使得第三个成员的偏移量变成8。 
        对照第二条,结构体大小等于最后一个成员的偏移量加上其大小,上面的例子中计算出来的大小为12,满足第二条原则,所以该结构体的大小便是12.

再看一个满足第一条,不满足第二条的情况 
struct stu_2 

       int k; 
       short t; 
}; 
        成员k的偏移量为0;成员t的偏移量为4,都不需要调整。但计算出来的大小为6,显然不是成员k大小的整数倍。因此,编译器会在成员t后面补上2个字节,使得结构体的大小变成8从而满足第二个要求。所以该结构体的大小为8. 
由此可见,大家在定义结构体类型时需要考虑到字节对齐的情况,不同的顺序会影响到结构体的大小。对比下面两种定义顺序。 
struct stu_3 

       char c1; 
       int i; 
       char c2; 
};

struct stu_4 

       char c1; 
       char c2; 
       int i; 
}; 
        虽然结构体stu3和stu4中成员都一样,但sizeof(struct stu3)的值为12而sizeof(struct stu4)的值为8。

如果结构体中的成员又是另外一种结构体类型时应该怎么计算呢?只需把其展开即可。但有一点需要注意,展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。看下面的例子: 
struct stu_5 

       short i; 
       struct 
       { 
              char c; 
              int j; 
       }ss; 
       int k; 
}; 
        结构体stu5的成员ss.c的偏移量应该是4,而不是2。整个结构体大小应该是16。 
如何给结构体变量分配空间由编译器决定,以上情况针对的是Windows XP下的VC 6.0。其他平台的C编译器可能会有不同的处理。 
示例代码:

#include <stdio.h>
 
struct  stu
{
    int  i;
    char  c;
    int  k;
};   //大小为12
 
struct  stu_2
{
    int  k;
    short  t;
};   //大小为8
 
struct  stu_3
{
    char  c1;
    int  i;
    char  c2;
};   //大小为12
 
struct  stu_4
{
    char  c1;
    char  c2;
    int  i;
};   //大小为8
 
struct  stu_5
{
    short  i;
    struct
    {
        char  c;
        int  j;
    } ss;
    int  k;
};   //大小为16
 
struct stu_6
{
    int i;
    char j;
    char k;
}; //大小为8

转自:http://www.cnblogs.com/ppboy_dxh/archive/2013/08/21/3273376.html

时间: 2024-10-05 23:27:06

计算结构体大小的相关文章

[C/C++标准库]_[初级]_[计算结构体成员的偏移量]

场景: 1. C结构体里计算结构体的偏移量平常看来没什么必要,但是放到插件结构的设计里就有必要了,比如只能使用偏移量访问的场景,而不能使用引用成员变量的场景. 2. 在设计一致性的接口时,公用的接口不怎么变化的,但是插件模块的结构可以不需要根据统一结构来设计,他们只需要提供偏移量给公用接口调用就行了,不同的插件 可能偏移量不一致,因为他们可以独立实现.公用接口就可以通过偏移量来访问不同的变量. 3. 可以使用stddef.h文件里的  offsetof /* Define offsetof ma

计算结构体首地址的技巧

struct ABC { int a; int b; int c; }; +----------+ <------我们需要计算的是这个地址. | a(4Byte) | +----------+ <------这个地址是已知的. | b(4Byte) | +----------+ | c(4Byte) | +----------+ 通过上图可看出,只需要把当前知道的成员变量的地址ptr,减去它在结构体当中相对偏移量(4),就得到了结构体的首地址(ptr-4). 设计一个type类型的结构体,起始

结构体大小

对齐规律:占用最大成员类型的整数倍,每个成员的对齐地址为该成员类型的整数倍 struct { int a; 0-3 char b;4-5 int c;8-11 }:12 含位域: 使用位域的主要目的是压缩存储,其大致规则为:1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止: struct test {  char a:1;  char :2;  char b:3;  char c:2; }; test t1; int l

字节对齐与结构体大小

#pragma pack (n) /*指定按n字节对齐*/   不写这句默认n =8 设真正的对齐长度为m字节 如果n>结构体中数据类型(包括类类型)长度最大的数据类型长度,m = 结构体中最大数据类型长度 否则 m = n 总之,真正的对齐长度m为指定对齐长度n与结构体中最大类型长度中的较小值. 规则: 1. 结构体变量的首地址能够被m所整除: 2. 结构体每个成员相对于结构体首地址的偏移量都是m的整数倍,如有需要编译器会在成员之间加上填充字节: 3. 结构体的总大小为m的整数倍,如有需要编译

sizeof()计算结构体的大小

简要说明:结构体成员按照定义时的顺序依次存储在连续的内存空间,但是结构体的大小并不是简单的把所有成员大小相加,而是遵循一定的规则,需要考虑到系统在存储结构体变量时的地址对齐问题. 一.没有成员的结构体占用的空间是多少个字节? 答案是:1个字节. 这就是实例化的原因(空类同样可以被实例化),每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类或空结构体(C++中结构体也可看为类)隐含的加一个字节,这样空类或空结构体在实例化后在内存得到了独一无二的地址,所以空类所占的内存

C++中的空类与空结构体大小

今天面试遇到了一个很有意思的问题,即空结构体在C++中所占的内存大小是多少?参见如下代码: #include <iostream> struct S0 { }; int main() { std::cout << sizeof S0 << std::endl; return 0; } 面试官当场提醒了我一下,说如果S0对象所占用的内存大小为0,那么将可以申请无限多个此类型的对象数组,并且大小永远为0.我当时觉得有点道理,不过转念一想,还是有点疑惑. 回来研究了一下,原来

c语言结构体大小 sizeof(struct A)

1,数据类型自身对齐 数据类型的起始地址为其大小的整数倍 2,结构体的自身对齐 结构体的自身对齐值为其中最大的成员大小 3,指定对齐 可以使用关键词#pragma pack(1) 来指定结构体的对齐值 4,有效对齐值 有效对齐值为自身对齐值与指定对齐值中较小的一个.(即指定对齐值超过自身对齐值无意义) 1 #include<stdio.h> 2 struct { 3 int a; //单个为4 4 char b[3]; // 单个大小为1 因为是数组总和为3 5 double c; //单个为

sizeof求结构体大小

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #include <iostream> using namespace std; /**  * 1 默认边界对齐  *   1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除(结构体对象作为结构体变量);  *   2) 结

计算结构体的大小

typedef struct { int num:16; //指定num所占空间为16位,即2字节 }A1; typedef struct { int num:16; //3个16位,本来为6字节,补齐为8字节 int num1:16; int num2:16; }A2; typedef struct { int num:8; //1个8位,本来为1字节,补齐为4字节 }A3; typedef struct { int num:8; //3个8位,本来为3字节,补齐为4字节 int num1:8