`

C语言内存对齐详解(2)

阅读更多

接上一篇:C语言内存对齐详解(1)

  VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。VC 中提供了#pragma pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况:

第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式;

第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。

结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。下面举例说明其用法:

#pragma pack(push) //保存对齐状态 
#pragma pack(4)//设定为4字节对齐 
struct test 
{ 
char m1; 
double m4; 
int m3; 
}; 
#pragma pack(pop)//恢复对齐状态

 以上结构的大小为16,下面分析其存储情况,首先为m1分配空间,其偏移量为0,满足我们自己设定的对齐方式(4字节对齐),m1占用1个字节。接着开始为 m4分配空间,这时其偏移量为1,需要补足3个字节,这样使偏移量满足为n=4的倍数(因为sizeof(double)大于n,m4占用8个字节。接着为m3分配空间,这时其偏移量为12,满足为4的倍数,m3占用4个字节。这时已经为所有成员变量分配了空间,共分配了4+8+4=16个字节,满足为n的倍数。如果把上面的#pragma pack(4)改为#pragma pack(16),那么我们可以得到结构的大小为24。

再看下面这个例子:

#pragma pack(8)
struct S1{
 char a;
 long b;
};

struct S2 {
 char c;
 struct S1 d;
 long long e;
};
#pragma pack()

成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐.

也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节.

S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8;

S2 中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,sizeof(S2)为24个字节.

这里有三点很重要:

1.每个成员分别按自己的方式对齐,并能最小化长度。

2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度。

3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐。

分享到:
评论

相关推荐

    C语言字节对齐详解

    ### C语言字节对齐详解 #### 一、什么是对齐,以及为什么要对齐 现代计算机内存是由一个个字节组成的,理论上来说,任何类型的变量都可以从任意地址开始存放。但在实际操作中,为了提高访问效率,不同的数据类型...

    C语言字节对齐问题详解

    C语言字节对齐问题详解 C语言中的字节对齐问题是指在编译器将C语言程序编译成机器代码时,对变量的存储方式进行调整,以提高存取效率和减少存储空间。字节对齐是指在内存中将变量按照一定的规则排列,以便在访问...

    C语言数据存储对齐详解

    C语言中的数据存储对齐是编译器为了提高内存访问效率和硬件兼容性而采用的一种策略。它涉及到如何在内存中安排数据结构的各个成员,确保数据读取和写入时能够快速高效地进行。对齐规则主要有以下几点: 1. **成员按...

    语言:内存字节对齐详解

    例如,设置`#pragma pack(2)`会让编译器按照2字节对齐,这对于理解和调试涉及内存布局的代码非常有用。 在结构体中,编译器会根据每个成员的数据类型和指定的对齐值来调整成员的位置,使得每个成员的地址满足有效...

    c语言字节对齐

    ### C语言中的字节对齐详解 #### 一、引言 字节对齐是C语言编程中的一个重要概念,尤其在处理复杂数据结构时尤为重要。本文将深入探讨字节对齐的基本原理、目的以及如何在实际开发中进行合理配置。 #### 二、字节...

    内存对齐 详细介绍内存对齐的原理

    ### 内存对齐原理详解 #### 一、什么是内存对齐? 在计算机科学中,内存对齐(Memory Alignment)是指数据类型与内存地址之间的关系。简单来说,就是指数据结构(尤其是结构体中的成员)在内存中的起始地址应该...

    5分钟搞定内存字节对齐

    C语言内存字节对齐详解 在C语言中,内存字节对齐是指编译器为了提高程序执行效率和可移植性,而对结构体成员在内存中的存储方式进行的调整。这个调整是基于体系结构的对齐规则,旨在提高程序的执行效率和可移植性。...

    C语言中的字节对齐详解。

    C语言中的字节对齐详解 字节对齐是一种内存存储方式,在现代计算机中,内存空间都是按照byte划分的。在理论上讲,似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定...

    c语言实例详解

    - 内存对齐:理解内存对齐的重要性,以及如何影响变量在内存中的布局。 8. **文件操作** - 打开与关闭文件:掌握fopen()和fclose()函数的使用,进行文件的读写操作。 - 文件读写:学习fread(), fwrite(), fgets...

    c语言开发实例详解

    - 内存对齐与性能优化:了解内存对齐的影响及如何通过内存管理优化程序性能。 9. **实例详解** - 简单的程序设计:如计算器、猜数字游戏等。 - 小型游戏:例如井字游戏、猜单词游戏等,这些实例将帮助你综合运用...

    C语言、C++内存对齐问题详解

    本文将深入解析C语言和C++中的内存对齐问题。 首先,内存对齐的主要目的是提高程序执行的效率。计算机的处理器在处理数据时,通常会一次性读取或写入多个字节的数据,例如,32位处理器可能一次处理4个字节。如果...

    c语言结构体知识详解

    2. 结构体成员变量内存对齐 内存对齐是指编译器在分配结构体内存时,会按照一定的规则对结构体的成员进行排列,以优化CPU的访问速度。具体来说,每个成员变量都会被放置在满足其对齐要求的地址上。例如,一个`short...

    C语言memset用法详解.zip

    - `memset`不能用于填充浮点数数组,因为浮点数的内存表示方式不是字节对齐的,可能会导致意想不到的结果。 - 在处理大内存区域时,`memset`比循环更高效,因为它通常由编译器优化成汇编级别的指令,直接操作内存...

    C语言常见内存错误

    ### C语言常见内存错误详解 #### 一、内存泄露 内存泄露是指在程序运行过程中,开发者在堆上分配的内存,如果没有及时释放,就会导致这部分内存无法被再次利用,最终可能导致整个系统的可用内存逐渐减少。虽然一两...

    C语言每日一题:结构体的内存大小

    ### C语言结构体内存对齐详解 在C语言中,结构体是一种复合数据类型,它允许程序员将不同类型的变量组织在一起作为一个单元。本篇文章将详细解释C语言中的结构体内存对齐原理,并通过一个具体的例子来说明如何计算...

Global site tag (gtag.js) - Google Analytics