对于结构体中内存对齐的简单说明

结构体内存对齐的原因:

在运行一个结构体时,编译器需要给结构体中的每个变量成员分配内存空间,如这样一个结构体中

typedef struct A

{

char c1;

int i;

int j;

}A;

对其内存空间分配问题进行分析,如若不进行内存对齐,它的内存空间是:

char类型变量c1占1个字节,紧接着int类型变量i与j分别占4个字节,总有9个字节,在访问时,如图1,访问次数较多;在图2中,总有12个字节空间,虽然浪费了c1后的三个字节空间,访问次数却变少,会很大程度上节省了时间,提高了效率。用一句话概括“浪费空间用来节省时间”,这就是结构对齐的主要原因。

结构体内存对齐求其大小:

首先来看这样一个结构体

typedef struct A

{

char c1;

int i;

}A;

int main()

{

A sa;

printf("%d\n",sizeof(A));

printf("%p\n",&(sa.c1));

printf("%p\n",&sa);

return 0;

}

其输出结果:8和两个相同地址。

在输出c1地址和sa的地址相同,所以结构体第一个成员变量是从内存的第一个字节空间开始的,接下来要思考为什么A的空间输出大小为8了?

首先,我们先要知道结构体默认对齐数在VS中为8,在Linux为4,现在以VS举例说明:

如上图中,char类型c1占用第一个字节,为偏移量为0的第一个字节(原因在上面已经解释),int类型变量i从偏移地址为4的字节空间开始占用四个字节,为什么从偏移地址为4这一字节开始,是以类型int字节数4的整数倍的偏移量的字节空间开始占用的,而上4的字节空间没被占用,所以从4开始,(同理char类型占用空间则为1的整数倍的偏移地址开始,double从8的整数倍的偏移地址开始等等),而结构体所占的位数要是结构体成员中所占位数最长的那个数据变量的整数倍,所以在此问题中4为最长,它的整数倍为8,所以占8个字节,c1后面的三个字节与浪费,但是与i对齐。

在举一个例子:

typedef struct s1

{

int i;

char j;

int a;

double b;

}s1

看到这个程序,首先明白这个结构体所占位数为double型字节为8的整数倍,然后分析:

int i占4个字节,char j占一个字节,j后面的3个字节浪费与i对齐;然后int a占四个字节,偏移地址从8开始到11,最后double b则从偏移地址16开始到23,所以总共占用24个字节空间,int a后的偏移地址12、13、14、15字节空间为了结构体对齐浪费掉,而24个字节正好为8的整数倍,所以当输出时其输出结果为:24

这就为结构体对齐的原因及求大小的基本知识,当然,在求大小时还有许多特殊情况,如:

(1)结构体中定义数组时的解法过程;

(2)结构体中嵌套另一个结构体时的解法过程等等

这些请看下一条博客的分析,这也是第一次第一条博客,所以以上分析可能有许多瑕疵与问题,还请能够指正指正!

时间: 2024-10-10 10:58:25

对于结构体中内存对齐的简单说明的相关文章

C语言 结构体的内存对齐问题与位域

http://blog.csdn.net/xing_hao/article/details/6678048 一.内存对齐 许多计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对 齐,而这个k则被称为该数据类型的对齐模数(alignment modulus).当一种类型S的对齐模数与另一种类型T的对齐模数的比值是大于1的整数,我们就称类型S的对齐要求比T强(严格),而称T比S弱(宽 松).这种强制的要求一来简化了处

C++/CLI 托管C++之结构体封装(内存对齐#pragma pack)【9】

CLI封装涉及内存对齐的结构体时,使用的是StructLayoutAttribute,指定Pack为1.4.8等属性. [1]C++导出函数,使用 1位对齐 #pragma pack(push) #pragma pack(1) typedef struct _testStru2 { int iVal; char cVal; __int64 llVal; }testStru2; #pragma pack(pop) //4.2 结构体边界对齐 EXPORTDLL_CLASS void Struct_

3.c语音结构体成员内存对齐详解

一.关键一点 最关键的一点:结构体在内存中是一个矩形,而不是一个不规则形状 二.编程实战 1 #include <stdlib.h> 2 #include <stdio.h> 3 4 struct A 5 { 6 int a; 7 char b; 8 }; 9 10 int main() 11 { 12 struct A a; 13 a.a = 1; 14 a.b = 1; 15 printf("%p\n", &a); 16 17 system(&quo

C结构体中数据的内存对齐问题

转自:http://www.cnblogs.com/qwcbeyond/archive/2012/05/08/2490897.html 32位机一般默认4字节对齐(32位机机器字长4字节),64位机一般默认8字节对齐(64位机机器字长8字节) 1.先看下面的例子:struct A{   char c1;   int i;   short s;   int j;}a; struct B{   int i;   int j;     short s;   char c1;}b; 结构A没有遵守字节对

【C语言】结构体中的内存对齐问题

话说大家有没有发现结构体中的内存对齐问题很有意思呢?我们这一次就一起研究一下这个问题为什么值得人探讨. 结构体内存对齐有三个原则; 1.数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储). 2.结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有s

C语言结构体在内存中的存储情况探究------内存对齐

条件(先看一下各个基本类型都占几个字节): void size_(){ printf("char类型:%d\n", sizeof(char)); printf("int类型:%d\n", sizeof(int)); printf("float类型:%d\n", sizeof(float)); printf("double类型:%d\n", sizeof(double)); return; } 结果: 先来一下, 这个结构体在内

VC中结构体的内存布局

看了 VC++中内存对齐 这篇文章,感觉说复杂了,根据我的总结,要算出结构体的内存大小和偏移量,只要清楚结构体各成员的内存布局就行了,下面介绍一下我总结的规则,有不对之处,欢迎回复. 1.实际PACK值根据默认值.声明值.成员值的最小值得到.默认值在32位系统中为4,声明值则是使用#pragma pack(n)声明的值,如没有则忽略,成员最小值则是指结构体中最大的一个数据类型的大小,如int为4,short为2...,举例: #pragma pack(8) struct sta { char a

结构体在内存中所占字节大小计算

作者 :卿笃军 今天上课,老师给我们演示了一下,计算结构体在内存中所占的字节大小.开始给了我们几个例子,然后要我们自己摸索出规律. 注:以下测试全是在win7_64bit  Devcpp 5.5.3环境下测试的.(char 1字节,int 4字节, double 8字节). 也许:你可能认为下面这个答案是 1+4 = 5   (×) #include <stdio.h> struct node { char a; int b; }; int main() { struct node QING;

结构体中的数据对齐

c语言结构中需要注意的就是数据存储的对齐方式. 对齐的好处:对齐主要是为了方便数据的访问,提高计算机的处理速度,但同时它会浪费内存空间. CPU的优化规则大致是这样的:对于n字节的元素,它的首地址能被n整除,才能获得最好的性能. 对齐的使用原则: 1.一般的基本对齐原则是按着最大的基本类型的长度进行对齐.较小的元素可以组合起来填充一段内存,实现基本的对齐.前提是其满足条件2. 2.结构体中的元素也要满足一定的分布条件,就是元素的存储起始地址要满足能够整除该元素类型的长度. 3.在结构体中存在结构