struct和union在内存中占用空间大小的计算

来源:互联网 发布:anaconda与python版本 编辑:程序博客网 时间:2024/06/05 03:42

在linux下基本数据类型使用内存空间大小

数据类型 32位系统 64位系统 _Bool 1字节 1字节 char 1字节 1字节 short 2字节 2字节 int 4字节 4字节 long 4字节 8字节 long long 8字节 8字节 float 4字节 4字节 double 8字节 8字节 long double 12字节 16字节 指针 4字节 8字节 enum 4字节 4字节

内存对齐

在32位系统下,gcc的对齐方式为1,2,4,默认为4字节对齐。
在64为系统下,gcc的对齐方式为1,2,4,8,默认为8字节对齐。


union联合体占用内存空间的大小的计算

union数据类型的大小计算方法是: 联合体中占用内存空间最大的字段加上填充字节后的和是联合体中占用内存空间最大的字段的整数倍。(max+n) / x 的结果是一个整数,result = max+n
max 是union中占用内存空间最大的字段占用的内存大小,大于等于1的整数。
n 是填充字节,非负整数。
x 是union中占用内存空间最大的一个基本数据类型占用的内存空间大小,大于等于1的整数。
result 是union数据类型实际上在内存中占用的内存大小,大于等于1。


  • 举例:

一:

union a{    char a;    int b;    char c[10];};

这个联合体占用12个字节的内存空间。根据上面的计算公式计算是:(10+2)/4。

二:

struct z{    double a;    short b;    short c;    char d[3];    char e;};union c{    int a;    double b;    struct z c;};

这个联合体占用的内存空间大小是:16个字节。(16+0)/16


struct结构体占用内存空间大小的计算

结构体中每个字段相对于结构体首地址的偏移量是这个字段的数据类型占用的内存空间大小的整数倍,如果不是整数倍,那么,在当前字段前填充字节,直到偏移量是本字段数据类型占用内存空间大小的整数倍。
为了使内存对齐,结构体中所有字段占用内存空间字节数要是本系统内存对齐数的整数倍,如果不是整数倍,那么,在结构体最后一个字段后面填充字节,直到结构体占用的内存空间字节数是系统内存对齐数的整数倍后,才是结构体实际占用的内存空间大小。

  • 举例:

一:

struct v{    double a;    short b;    char c[3];    short d;    char e;};

结构体 struct v 占用空间的计算:

  • 1、结构体中的a字段其数据类型为double,占用内存空间为8个字节,相对于结构体的首地址的偏移量为0,是本字段数据类型占用内存空间的整数倍 0-7

  • 2、结构体中的b字段其数据类型为short,占用内存空间为2个字节,相对于结构体的首地址的偏移量为8,是本字段的数据类型占用内存空间的整数倍 8-9

  • 3、结构体中的c字段其数据类型为char,占用内存空间为3个字节,但是一个数组,其数据类型占用内存空间为1个字节,相对于结构体的首地址的偏移量为10,是本字段的数据类型占用内存空间的整数倍 10-12+1

  • 4、结构体中的d字段其数据类型为short,占用内存空间为2个字节,相对于结构体的首地址偏移量为13,不是本字段的数据类型占用内存空间的整数倍,在此(d字段前,c字段后)填充一个字节后,偏移量为14,是本字段的数据类型占用内存空间的整数倍 14-15

  • 5、结构体中的e字段其数据类型为char,占用内存空间为1个字节,相对于结构体的首地址偏移量为16,是本字段的数据类型占用内存空间的整数倍 16-16+3

  • 6、计算到这里,就需要区一下系统的位数了:
    如果是32位系统:本结构体中的5个字段共占用了17个字节,但是这个结构体的首地址偏移17个字节处的地址不是32位计算机的4字节对齐的地址,需要在本结构体中的e字段后面填充3个字节。
    所以,本数据类型在32位机中实际占用的内存空间是20字节。
    如果是64位系统:本结构体中的5个字段共占用了17个字节,但是这个结构体的首地址偏移17个字节处的地址不是64位计算机的8字节对齐的地址,需要在本结构体中的e字段后面填充7个字节。
    所以,本数据类型在64位机中实际占用的内存空间是24字节。

二:

struct r{    double a;    short b;    short c;    char d[3];    char e;};

结构体 struct r 占用空间的计算:

  • 1、结构体中a字段的数据类型是double,占用内存空间大小是8个字节。相对于本结构体首地址的偏移量为0,是本字段数据类型占用空间大小的整数倍

  • 2、结构体中b字段的数据类型是short,占用内存空间大小是2个字节。相对于本结构体首地址的偏移量为8,是本字段数据类型占用空间大小的整数倍

  • 3、结构体中c字段的数据类型是short,占用内存空间大小是2个字节。相对于本结构体首地址的偏移量为10,是本字段数据类型占用空间大小的整数倍

  • 4、结构体中d字段的数据类型是char,占用内存空间大小是3个字节。但是本字段的数据类型占用内存空间大小是1个字节。相对于本结构体首地址的偏移量为12,是本字段数据类型占用空间大小的整数倍

  • 5、结构体中e字段的数据类型是char,占用内存空间大小是1个字节,相对于本结构体首地址的偏移量为15,是本字段数据类型占用空间大小的整数倍

  • 6、计算到这里需要区分系统的位数了:
    在32位系统中:本结构体中所有字段占用的内存空间大小是16个字节。本结构体首地址偏移16个字节处是32位机4字节对齐的地址。
    所以,本结构体在32位机中实际占用的内存空间大小是16个字节。
    在64位系统中:本结构体中所有字段占用的内存空间大小是16个字节。本结构体首地址偏移16个字节处是64位机8字节对齐的地址。
    所以,本结构体在64位机中实际占用的内存空间大小是16个字节。




  • 上面的两个结构体中的数据类型都是一样的,只是字段的排列方式不一样 但是,却导致了两个结构体在内存中占用的内存空间大小不相同。
  • 为了能够让你定义的结构体尽可能的在内存中占用最小的空间,在定义 结构体中的字段的时候,要将将占用内存空间最大的数据类型的字段定义在结构体的前面。
  • 结构体中的结构体或者联合体占用内存空间的大小,其实就是这个结构体或者联合体本身在内存中占用内存空间的大小

本文内容测试平台

  • 32位机:

    操作系统:$ uname -srvmpio
    Linux 3.19.0-56-generic #62-Ubuntu SMP Thu Mar 10 22:39:28 UTC 2016 i686 i686 i686 GNU/Linux

    编译器:$ gcc -v
    gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13)

  • 64位机:

    操作系统:$ uname -srvmpio
    Linux 4.4.0-53-generic #74-Ubuntu SMP Fri Dec 2 15:59:10 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

    编译器:$gcc -v
    gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)

0 0