struct内存对齐

内存对齐其实是为了在程序运行的时候更快的查找内存而做的一种编译器优化。

我们先看这样一个例子:

 1 #include <iostream>
 2 using namespace std;
 3
 4 struct vpoet
 5 {
 6     int a;   //4 bytes
 7     char b;   //1 bytes
 8     double c;  // 8 bytes
 9     char *d;   //4 bytes
10     int e;     //4 bytes
11 };
12
13 int main()
14 {
15     cout<<"sizeof(vpoet)="<<sizeof(vpoet)<<endl;
16     return 0;
17 }

运行结果:

这个结构体大小为24个字节,但是我们仔细算一算其字节数

发现其实际上只有4+1+8+4+4=21个字节,那是如何算

出来24个字节的呢,其实在默认情况下编译器是按照结构体

中所占字节最大的成员来进行内存对齐的。比如在结构体

vpoet中最大的是double double占8个字节,那么编译器

默认按8个字节的方式对齐那么编译器将按照大于实际字节数

的double最小整数倍来进行内存分配。因而这里实际是在结构体

的成员b后面填充了三个字节用于对齐。

那么问题来了,对齐方式可以改吗?

可以我们可以在文件头加上

1 #pragma pack(n)

来改变内存对齐的字节数

比如当我们按照一个字节对齐的时候:

 1 #include <iostream>
 2 using namespace std;
 3 #pragma pack(1)
 4
 5 struct vpoet
 6 {
 7     int a;   //4 bytes
 8     char b;   //1 bytes
 9     double c;  // 8 bytes
10     char *d;   //4 bytes
11     int e;     //4 bytes
12 };
13
14 int main()
15 {
16     cout<<"sizeof(vpoet)="<<sizeof(vpoet)<<endl;
17     return 0;
18 }

运行结果:

当我们按照1字节对齐的时候,编译器将为

该结构体分配本身实际大小的字节数

当我们以2字节对齐的时候

1 #pragma pack(2)

此时的输出结果为:

当我们按照2字节对齐的时候,编译器将为结构体

成员b后面填充一个空字节用于内存对齐。

记住这样一个规律:

默认情况下编译器将按照实际结构体中占内存字节数

最大的成员的整数倍进行分配,该最大的整数倍

应正好大于或者等于结构体实际所占的内存字节数

时间: 2024-10-31 07:30:40

struct内存对齐的相关文章

struct内存对齐1:gcc与VC的差别

struct内存对齐:gcc与VC的差别 内存对齐是编译器为了便于CPU快速访问而采用的一项技术,对于不同的编译器有不同的处理方法. Win32平台下的微软VC编译器在默认情况下采用如下的对齐规则: 任何基本数据类型T的对齐模数就是T的大小,即sizeof(T).比如对于double类型(8字节),就要求该类型数据的地址总是8的倍数,而char类型数据(1字节)则可以从任何一个地址开始.Linux下的GCC奉行的是另外一套规则:任何2字节大小(包括单字节吗?)的数据类型(比如short)的对齐模

C或C++中struct内存对齐计算精简方案

struct占用内存计算方法: 假设struct的起始地址是0x00000000,则从起始地址开始到当前元素为止所占用的空间“和”,必须是下一个成员空间的整数倍(未达到整数倍的部分留空),当到达最后一个成员的时候,即要计算总struct空间的时候,这个空间必须是所有成员中最大基本元素的整数倍. 如果struct的某一个元素是数组,只需对齐到基本元素即可,不用对齐整个数组 所以,定义结构体的时候,尽量将同一类型的变量声明在一起,而且按照占用空间大小,使用由小到大排列或者由大到小排列的方式,例如占用

[C++] struct 内存对齐问题

每个变量相对于结构起始地起始地址都应该是这种变量长度的整数倍. [1] http://blog.163.com/[email protected]/blog/static/864037152011914105819906/

&lt;转&gt; Struct 和 Union区别 以及 对内存对齐方式的说明

转载地址:http://blog.csdn.net/firefly_2002/article/details/7954458 一.Struct 和 Union有下列区别: 1.在存储多个成员信息时,编译器会自动给struct第个成员分配存储空间,struct 可以存储多个成员信息,而Union每个成员会用同一个存储空间,只能存储最后一个成员的信息. 2.都是由多个不同的数据类型成员组成,但在任何同一时刻,Union只存放了一个被先选中的成员,而结构体的所有成员都存在. 3.对于Union的不同成

内存对齐与ANSI C中struct型数据的内存布局 【转】

转自:http://blog.chinaunix.net/uid-25909619-id-3032209.html 当在C中定义了一个结构类型时,它的大小是否等于各字段(field)大小之和?编译器将如何在内存中放置这些字段?ANSI C对结构体的内存布局有什么要求?而我们的程序又能否依赖这种布局?这些问题或许对不少朋友来说还有点模糊,那么本文就试着探究它们背后的秘密. 首先,至少有一点可以肯定,那就是ANSI C保证结构体中各字段在内存中出现的位置是随它们的声明顺序依次递增的,并且第一个字段的

【转】C/C++ struct/class/union内存对齐

原文链接:http://www.cnblogs.com/Miranda-lym/p/5197805.html struct/class/union内存对齐原则有四个: 1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节, 则要从4的整数倍地址开始存储),基本类型不包括stru

C/C++ struct/class/union内存对齐

struct/class/union内存对齐原则有四个: 1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节, 则要从4的整数倍地址开始存储),基本类型不包括struct/class/uinon. 2).结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部"

内存对齐与自定义类型

一.内存对齐 (一).为什么会有内存对齐? 1.为了提高程序的性能,数据结构(尤其是栈)应该尽可能的在自然边界上对齐.原因是为了访问未对齐的内存,处理器需要进行两次访问,而访问对齐的内存,只需要一次就够了.这种方式称作"以空间换时间"在很多对时间复杂度有要求问题中,会采用这种方法. 2.内存对齐能够增加程序的可移植性,因为不是所有的平台都能随意的访问内存,有些平台只能在特定的地址处处读取内存. 一般情况下内存对齐是编译器的事情,我们不需要考虑,但有些问题还是需要考虑的,毕竟c/c++是

内存对齐,大端字节 &nbsp; 序小端字节序验证

空结构体:对于空结构体,就是只有结构体这个模子,但里面却没有元素的结构体. 例: typedef struct student { }std: 这种空结构体的模子占一个字节,sizeof(std)=1. 柔性数组: 结构体中最后一个元素可以是一个大小未知的数组,称作柔性数组成员,规定柔性数组前面至少有一个元素. typedef struct student { int i; char arr[];     //柔性数组成员 }std: sizeof(std)=4; sizeof求取该结构体大小是