C 语言中结构体中成员所占内存的大小

在C99标准中,对于内存对齐的细节没有作过多的描述,具体的实现交由编译器去处理,所以在不同的编译环境下,内存对齐可能略有不同,但是对齐的最基本原则是一致的,对于结构体的字节对齐主要有下面两点:

  1. 结构体每个成员相对结构体首地址的偏移量(offset)是对齐参数的整 数倍,如有需要会在成员之间填充字节。编译器在为结构体成员开辟空间时,首先检查预开辟空间的地址相对于结构体首地址的偏移量是否为对齐参数的整数倍,若是,则存放该成员;若不是,则填充若干字节,以达到整数倍的要求。这句话中的对齐参数是取每个变量自身对齐参数和系统默认对齐参数#pragma pack(n)中较小的一个。举个简单的例子,比如在结构体A中有变量int a,a的自身对齐参数为4(环境为windows/DEV),而DEV默认的对齐参数为8,取较小者,则对于a,它相对于结构体A的起始地址的偏移量必须是4的倍数。

  2. 结构体变量所占空间的大小是对齐参数大小的整数倍。如有需要会在最后一个成员末尾填充若干字节使得所占空间大小是对齐参数大小的整数倍。它是取结构体中所有变量的对齐参数的最大值和系统默认对齐参数#pragma pack(n)比较,较小者作为对齐参数。

(1)struct结构体变量大小等于结构体中的各个成员变量所占内存大小总和,union共用体变量大小等于共用体结构中占用内存最大的成员的内存大小; 联合体中占用内存空间最大的字段加上填充字节(对齐字节后所需字节数)。

(2)枚举类型,指一个被命名的整型常数的集合。即枚举类型,本质上是一组常数的集合体,只是这些常数有各自的命名。枚举类型,是一种用户自定义数据类型,一般是int数据类型,4个字节。

枚举变量,由枚举类型定义的变量。枚举变量的大小,即枚举类型所占内存的大小。由于枚举变量的赋值,一次只能存放枚举结构中的某个常数。所以枚举变量的大小,实质是常数所占内存空间的大小(常数为int类型,当前主流的编译器中一般是32位机器和64位机器中int型都是4个字节),枚举类型所占内存大小也是这样。

(3)指针其实就是地址, 与它所指的基类型无关, 更与C语言无关, 只与机器有关. 如果你的机器是16位寻址的, 那指针就是16位的,2个字节, 如果是32位寻址的, 指针也是32位的,4个字节.如果寻址是64位的,指针也是64位,8个字节。

看例题:

 

C 语言中结构体中成员所占内存的大小

首先,#pragma pack(2)   强制设定为2字节对

i   4字节

u  一个为13,一个为4,默认为4字节对齐;

     但是,该处强制为2字节对齐,实际为13+1=2*7=14字节

color   枚举类型的实例  4字节

4+14+4=22字节

C++中结构体中普通成员函数不占用类得内存。
但是如果有虚函数的话,要有一个虚表指针的内存
类最小是占用一个字节。即一个没有任何成员变量和虚函数的类占用1字节

声明是对一个变量的性质加以说明,并不为其分配存储空间。

函数(子程序)里声明的变量即局部变量,只用当调用子程序时才分配,退出子程序就取消。

主程序中声明变量时,如int i;float a【10】,声明的同时也就分配。

2、

typedef struct

{ char c;

short d;

static int a; }

C;

sizeof(C)= 4

正因为我们的a是静态变量,而静态数据成员的存放位置与结构体实例的存储地址无关(注意只有在C++中结构体中才能含有静态数据成员,而C中结构体中是不允许含有静态数据成员的)。a是单独存放在静态数据区的,因此用siezof计算其大小时没有将a所占的空间计算进来。