【C语言】变量占用内存的大小&&内存对齐

发布于:2024-04-29 ⋅ 阅读:(26) ⋅ 点赞:(0)
                 32位系统     64位系统
类型              大小           大小
char               1             1
char *             4             8

int                4             4
int  *             4             8
short              2             2
short int          2             2
long               4             4
long int           4             4
long long          8             8
unsigned long long 8             8

double             8             8
long double        8             8
float              4             4

bool               1             1

当然,你也可以用sizeof()来查看变量占用内存的大小

内存对齐

为什么会有内存对齐?

无论如何,为了提高程序的性能,数据结构(尤其是栈)应该尽可能在自然边界上对齐。原因在于为了访问未对齐的内存处理器需要作两次内存访问的操作,对齐后则只需一次,效率大大提升。

数据成员对齐规则

结构(struct)或联合(union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。

结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

#include<stdio.h>
typedef struct bb
{
 int id;             //[0]....[3]
 double weight;      //[8].....[15]
 float height;      //[16]..[19],总长要为8的整数倍,补齐[20]...[23]
}BB;

typedef struct aa
{
 char name[2];     //[0],[1]
 int  id;         //[4]...[7]
 double score;     //[8]....[15]    
 short grade;    //[16],[17]        
 BB b;             //[24]......[47]
}AA;

int main()
{
  AA a;
  printf("%d\n%d",sizeof(BB),sizeof(a));
  return 0;
}

输出结果为:

24
48

#pragma pack()

在代码前加一句#pragma pack(1),你会很高兴的发现,上面的代码输出为16 32

BB是4+8+4=16,aa是2+4+8+2+16=32;

这不是理想中的没有内存对齐的世界吗.没错,#pragma pack(1),告诉编译器,所有的对齐都按照1的整数倍对齐,换句话说就是没有对齐规则.

#pragma pack指令可以用来调整编译器的默认对齐方式,将会按照n个字节进行对齐。若直接使用#pragma pack()而不加参数则编译器会取消自定义字节对齐方式。

但是需要注意的是,按照n个字节对齐并非是每个数据都必须是n个字节。每个成员还是按照自己的方式对齐,只不过对齐时从对齐参数(通常是该类型的大小)和n中取较小的那个。

#include<stdio.h>
#pragma pack(8)
typedef struct bb
{
 int id;
 char ch;
}BB;
int main()
{
  printf("%d",sizeof(BB));
  return 0;
}

输出为:8

参考博文:

https://blog.csdn.net/hairetz/article/details/4084088

https://blog.csdn.net/czc1997/article/details/81090740