系统相关
首页 > 系统相关> > C/C++中struct中内存对齐规则

C/C++中struct中内存对齐规则

作者:互联网

前言

先来预热一下,下面两个简单的结构体,假设不在IDE运行测试,你能快速说出输出结果吗?不能,往下看。

struct B{
   int a;
   char b;
   char c;
};

struct C{
   char a;
   int b;
   char c;
};

cout<<"Size Of Struct B: "<<sizeof(struct B)<<endl;

cout<<"Size Of Struct C: "<<sizeof(struct C)<<endl;

发现一直不能快速计算出来,故怒总结本文,否则稍微改变一下结构体又会被蒙圈了,实在不能忍受这种感觉,本文力求给出最简单明了的方法。

内存对齐规则

强烈建议你先跳过下面无聊的规则,看完本文再来,如果你执意要看我也没办法…

1、没有#pragma pack宏的对齐规则

2、存在#pragma pack宏的对齐

#pragma pack (n)    //编译器将按照n个字节对齐  
#pragma pack ()     //取消自定义字节对齐方式

那么对齐规则就变成下面的

忽略了上面的对齐规则,下面来看看在C++中数据类型的内存分配大小。

数据类型字节大小
char 1
bool 1
short 2
int 4
long 4
float 4
double 8
long long 8
long double 8

攻略

确定一个结构体大小大致需要下面两个步骤即可

卧槽,对比上面凌乱的对齐规则,就上面两个步骤真可以求出结构体大小?不信?下面来看看实战分析

首先看看空结构体,C++编译器会在空类或空结构体中增加一个虚设的字节,以确保不同的对象都具有不同的地址。

struct A  
{  

}; 

cout<<"空结构体:"<<sizeof(struct A)<<endl;  //毫无疑问输出 1

接下来分析开头的两个结构体:(S2010+64位机器下进行调试,并将地址复制出来)

struct B{
 int a;
 char b;
 char c;
};

//测试:获取内存分配地址数据
 B b = {1,'a','b'};
 B *pb_s = &b     // 0x003efa8c
 int *pb_a = &b.a // 0x003efa8c
 char *pb_b = &b.b// 0x003efa90
 char *pb_c = &b.c// 0x003efa91

cout<<"Struct B:"<<sizeof(struct B)<<endl; //输出为8

分析:

再来看看第二个结构体

struct C{
 char a;
 int b;
 char c;
};

 C c = {'a',1,'b'};
 C *pc_s = &c     // 0x0047fa28
 char *pc_a = &c.a// 0x0047fa28
 int *pc_b = &c.b // 0x0047fa2c
 char *pc_c = &c.c// 0x0047fa30
	
 cout<<"Struct C:"<<sizeof(struct C)<<endl; //输出12

分析

好了,看到这里你可以回去看看内存的对齐规则,另外struct/class/union内存对齐原则都是一样的,但需要注意union的原理。遇到复杂情况,要做的就是冷静分析。如果有错误,欢迎指出!(不敢误人子弟啊)

标签:struct,int,整数倍,C++,char,对齐,字节
来源: https://www.cnblogs.com/maji233/p/11439880.html