c++内存中字节对齐问题详解

合集下载

c语言字节对齐原理

c语言字节对齐原理

c语言字节对齐原理C语言中的字节对齐原理是指在内存中分配变量存储空间时,为了提高访问效率和内存利用率,系统会按照一定的规则进行对齐操作。

字节对齐原理在C语言中非常重要,对于程序的正确性和性能都有着重要的影响。

字节对齐的原理是为了优化内存访问速度和空间利用率,避免因为不对齐而导致的性能降低。

在C语言中,变量的存储空间是以字节为单位进行分配的,而不同的数据类型在内存中所占的字节数是不同的。

字节对齐的目的是为了确保不同类型的变量在内存中的起始地址是对齐的,这样可以提高访问效率。

C语言中的字节对齐规则是由编译器来决定的,不同的编译器可能有不同的对齐规则。

一般来说,编译器会按照变量的自然对齐大小进行对齐。

自然对齐是指变量所占的字节数,例如char类型的变量自然对齐为1字节,int类型的变量自然对齐为4字节。

在进行字节对齐时,编译器会在变量之间插入一些空白字节,使得变量的起始地址能够满足对齐要求。

这样一来,虽然会浪费一些空间,但可以提高内存的访问效率。

例如,如果int类型的变量要求按4字节对齐,而其起始地址为0x1000,那么在其后紧接着的变量的起始地址就必须是0x1004,即起始地址必须是4的倍数。

字节对齐的规则并不是固定的,它受到编译器的影响。

有些编译器的默认对齐规则可能是按照变量的自然对齐大小来对齐的,而有些编译器可能会有一些特殊的对齐规则。

此外,开发人员也可以通过编译器提供的指令来手动控制字节对齐的方式。

字节对齐的原理和规则虽然复杂,但它对于程序的正确性和性能优化至关重要。

如果变量没有按照正确的对齐方式进行存储,可能会导致内存访问错误,甚至引发程序崩溃。

而且,字节对齐也会影响程序的性能,如果变量没有按照对齐要求进行存储,可能会导致内存访问速度变慢,从而影响程序的执行效率。

为了正确地使用字节对齐,开发人员需要了解编译器的对齐规则,并且在编写代码时遵循这些规则。

在一些特殊情况下,开发人员也可以使用编译器提供的指令来手动控制字节对齐的方式,以满足特定的需求。

c语言结构体中的数组字节对齐

c语言结构体中的数组字节对齐

C语言结构体中的数组字节对齐在C语言中,结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起。

结构体中常常包含多个成员变量,其中可能有数组类型的成员变量。

在结构体中使用数组时,需要了解数组字节对齐的概念和规则,以确保内存的最佳利用和访问的效率。

什么是字节对齐字节对齐是指在将数据存储在计算机内存中时,按照特定规则进行调整,以确保数据的存储和访问的效率。

字节对齐的规则可以对齐数据的起始地址或者数据的长度。

计算机中的数据存储是按照字节(Byte)来划分的,一个字节通常由8个二进制位组成。

字节对齐的主要目的是为了节省内存和提高访问效率。

在C语言中,结构体中的成员变量通常按照字节对齐的规则来排列。

C语言结构体中的数组字节对齐规则在C语言中,结构体中的数组字节对齐规则通常遵循以下原则:1.结构体的起始地址必须是所有成员变量所要求对齐方式的最小公倍数。

2.结构体中的每个成员变量的地址必须是它本身的大小的整数倍。

3.结构体的总大小必须是其最大成员变量大小的整数倍。

根据字节对齐规则,如果结构体中的成员变量的累计大小不是字节对齐的倍数,编译器会在成员变量之间添加填充字节,以满足对齐要求。

这些填充字节在结构体的占用空间中不可访问。

填充字节的目的是将后续成员变量的地址对齐,以提高内存访问效率。

数组字节对齐的示例为了更好地理解数组字节对齐的规则,我们来看一个示例。

#include <stdio.h>struct MyStruct {char c;int i;char arr[3];};int main() {struct MyStruct s;printf("sizeof(MyStruct) = %lu\n", sizeof(struct MyStruct));printf("sizeof(s.c) = %lu\n", sizeof(s.c));printf("sizeof(s.i) = %lu\n", sizeof(s.i));printf("sizeof(s.arr) = %lu\n", sizeof(s.arr));return 0;}输出结果:sizeof(MyStruct) = 12sizeof(s.c) = 1sizeof(s.i) = 4sizeof(s.arr) = 3在这个示例中,我们定义了一个包含一个字符类型变量、一个整型变量和一个长度为3的字符数组的结构体MyStruct。

c语言4字节对齐指令

c语言4字节对齐指令

c语言4字节对齐指令C语言是一种十分常用的编程语言,它被广泛应用于各种领域,如操作系统、数据库、游戏等。

在C语言中,内存对齐是一个非常重要的概念。

内存对齐是指将数据存储在内存中时,按照一定规则对数据进行排列的过程。

其中,4字节对齐指令是C语言中常用的一种内存对齐方式。

1. 什么是内存对齐?在计算机系统中,内存是由若干个字节组成的。

每个字节都有一个唯一的地址。

当我们定义一个变量时,计算机会为其分配一段连续的内存空间,并将变量值存储在该空间中。

但是,在实际应用中,我们会发现不同类型的变量在内存中占用的空间大小不同。

例如,在32位系统中,int类型变量占用4个字节,而char类型变量只占用1个字节。

由于计算机硬件结构的限制,读取未对齐的数据会导致性能下降或者出现异常情况。

因此,在将数据存储到内存中时需要进行内存对齐操作。

2. 为什么要进行4字节对齐?在C语言中,默认情况下采用的是字节对齐方式。

也就是说,变量在内存中的位置与其大小有关。

例如,一个int类型变量占用4个字节,那么它在内存中的地址必须是4的倍数。

而4字节对齐则是指将变量按照4个字节进行对齐。

这种方式可以提高内存访问速度,并且可以减少内存空间的浪费。

3. 如何进行4字节对齐?在C语言中,可以通过使用特定的编译指令来实现4字节对齐。

常用的指令包括#pragma pack(n)和__attribute__((aligned(n)))。

#pragma pack(n)指令用于设置结构体成员之间的间隔为n个字节。

例如,如果我们想要将一个结构体按照4字节进行对齐,则可以使用以下代码:```#pragma pack(4)struct test {char a;int b;short c;};```在上述代码中,由于设置了#pragma pack(4),因此结构体成员之间的间隔都为4个字节。

另外一种方法是使用__attribute__((aligned(n)))指令。

C语言字节对齐

C语言字节对齐

C语言字节对齐字节对齐的由来程序在运行时会将数据临时存放在内存中,芯片内核需要对这些数据进行计算,不断的读取内存以获得数据,并将计算结果写入内存。

计算机体系经过若干年的发展,最终确定了以8bits作为其基本的存储单元——byte(字节),这是每个地址所对应的最小访问单元,在C语言中对应一个char型的变量。

下图为芯片内核访问内存的示意图。

芯片内核通过控制总线控制内存的动作,通过地址总线告知内存地址,数据总线上出现交互的数据。

图1访问内存示意图假设上图是8位机的示意图,那么数据总线的宽度是8bits,由8根数据线组成,这样芯片内核与内存之间一次就可以同时交换8个bits的数据,正好是一个字节。

图中右侧的每个小格子代表一个存储地址,对应一个字节。

下面通过一段C语言代码来具体看看芯片内核与内存之间的数据交互过程。

char data[2];data[0]=2;data[1]=data[0]+1;第一行代码定义了2个字节的数组data。

假设data数组被编译到地址0x100,那么data[0]这个字节就被存储在地址为0x100的内存空间,data[1]这个字节就被存储在地址为0x101的内存空间。

第二行对应的硬件动作是将数据2存入到data[0]中,也就是将数据2存入到内存中的0x100地址,执行这条语句时,芯片内核对控制总线、地址总线和数据总线进行操作,控制总线上出现写信号,地址总线上出现数据0x100,数据总线上出现数据0x02。

此时内存就知道需要将数据2写入到地址0x100中,完成一次写操作。

第三行先读出data[0]中的数据,芯片内核将控制总线置为读信号,将地址总线置为0x100,此时,内存就会从其内部取出0x100地址中的数据,也就是数据2,2将出现在数据总线上,此时芯片内核就会通过数据总线读取到data[0]中的数据了。

接下来芯片内核计算2+1=3,需要将数字3写入到data[1]中,芯片内核将控制总线置为写信号,将地址总线置为0x101,将数据总线置为3,内存接收到这些信号后,就会将数据3存入到其内部0x101地址中,完成本次操作。

C语言的字节对齐及#pragmapack的使用

C语言的字节对齐及#pragmapack的使用

C语⾔的字节对齐及#pragmapack的使⽤C编译器的缺省字节对齐⽅式(⾃然对界)在缺省情况下,C编译器为每⼀个变量或是数据单元按其⾃然对界条件分配空间。

在结构中,编译器为结构的每个成员按其⾃然对界(alignment)条件分配空间。

各个成员按照它们被声明的顺序在内存中顺序存储(成员之间可能有插⼊的空字节),第⼀个成员的地址和整个结构的地址相同。

C编译器缺省的结构成员⾃然对界条件为“N字节对齐”,N即该成员数据类型的长度。

如int型成员的⾃然对界条件为4字节对齐,⽽double类型的结构成员的⾃然对界条件为8字节对齐。

若该成员的起始偏移不位于该成员的“默认⾃然对界条件”上,则在前⼀个节⾯后⾯添加适当个数的空字节。

C编译器缺省的结构整体的⾃然对界条件为:该结构所有成员中要求的最⼤⾃然对界条件。

若结构体各成员长度之和不为“结构整体⾃然对界条件的整数倍,则在最后⼀个成员后填充空字节。

例⼦1(分析结构各成员的默认字节对界条界条件和结构整体的默认字节对界条件):struct Test{char x1; // 成员x1为char型(其起始地址必须1字节对界),其偏移地址为0char x2; // 成员x2为char型(其起始地址必须1字节对界,其偏移地址为1float x3; // 成员x3为float型(其起始地址必须4字节对界),编译器在x2和x3之间填充了两个空字节,其偏移地址为4char x4; // 成员x4为char型(其起始地址必须1字节对界),其偏移地址为8};因为Test结构体中,最⼤的成员为flaot x3,因些此结构体的⾃然对界条件为4字节对齐。

则结构体长度就为12字节,内存布局为1100 1111 1000。

例⼦2:#include <stdio.h>//#pragma pack(2)typedef struct{int aa1; //4个字节对齐 1111char bb1;//1个字节对齐 1short cc1;//2个字节对齐 011char dd1; //1个字节对齐 1} testlength1;int length1 = sizeof(testlength1); //4个字节对齐,占⽤字节1111 1011 1000,length = 12typedef struct{char bb2;//1个字节对齐 1int aa2; //4个字节对齐 01111short cc2;//2个字节对齐 11char dd2; //1个字节对齐 1} testlength2;int length2 = sizeof(testlength2); //4个字节对齐,占⽤字节1011 1111 1000,length = 12typedef struct{char bb3; //1个字节对齐 1char dd3; //1个字节对齐 1int aa3; //4个字节对齐 001111short cc23//2个字节对齐 11} testlength3;int length3 = sizeof(testlength3); //4个字节对齐,占⽤字节1100 1111 1100,length = 12typedef struct{char bb4; //1个字节对齐 1char dd4; //1个字节对齐 1short cc4;//2个字节对齐 11int aa4; //4个字节对齐 1111} testlength4;int length4 = sizeof(testlength4); //4个字节对齐,占⽤字节1111 1111,length = 8int main(void){printf("length1 = %d.\n",length1);printf("length2 = %d.\n",length2);printf("length3 = %d.\n",length3);printf("length4 = %d.\n",length4);return0;}改变缺省的对界条件(指定对界)· 使⽤伪指令#pragma pack (n),C编译器将按照n个字节对齐。

c++字节对齐规则

c++字节对齐规则

c++字节对齐规则C++字节对齐规则是指在内存中创建数据结构时,变量的地址必须是某个特定值的倍数。

这个特定值称为对齐系数,通常是1、2、4、8等。

遵循字节对齐规则可以提高程序的性能和效率。

本文将介绍C++字节对齐规则的基本原理、对齐方式以及对齐的应用场景。

在C++中,字节对齐是为了优化内存访问的效率。

当变量被创建在内存中时,根据对齐系数,编译器会将变量的地址对齐到某个特定的地址。

这样一来,CPU在访问这些内存地址时可以更快地读取数据,提高了程序的运行效率。

C++中的对齐方式有两种,分别是数据成员对齐和结构体对齐。

在数据成员对齐中,每个数据成员的地址都必须是它自身长度和对齐系数中较大值的倍数。

结构体对齐则是指结构体的起始地址必须是结构体成员中最大对齐系数的倍数。

对齐方式的选择可以通过编译器的设置来进行调整。

一般来说,编译器会提供默认的对齐方式,但也可以通过一些特殊的指令或者预处理宏来设置自定义的对齐方式。

对于大多数应用场景来说,采用默认的对齐方式就可以满足需求。

字节对齐规则在实际开发中有很多应用场景。

首先,结构体对齐可以提高结构体对象数组的访问速度。

当一个结构体对象数组被创建在内存中时,根据结构体成员中最大的对齐系数,编译器会将每个结构体对象的起始地址对齐到这个系数的倍数上。

这样一来,在访问结构体数组时,CPU可以更快地进行内存读取,提高了程序的性能。

其次,字节对齐规则在跨平台开发中也非常重要。

由于不同平台上的CPU和操作系统对字节对齐的要求可能不同,因此在进行跨平台开发时,需要确保代码在不同平台上运行时,字节对齐的规则是一致的。

这可以通过使用特定的编译指令或者预处理宏来实现。

此外,字节对齐规则在处理网络协议、文件格式等底层数据结构时也非常常见。

在这些场景中,确保数据在内存中的排列方式与协议或者文件格式的要求一致非常重要。

如果不遵循字节对齐规则,可能会导致数据解析错误或者性能下降。

总结起来,C++字节对齐规则是为了提高程序性能和效率而设计的。

c语言结构体按1字节对齐

c语言结构体按1字节对齐

c语言结构体按1字节对齐在c语言中,结构体是一种自定义数据类型,作用是将若干个不同类型的数据组合在一起,形成一个新的数据类型。

在定义结构体时,我们需要考虑结构体中各个成员的内存对齐方式,这对程序的性能和内存占用都有很大的影响。

在c语言中,结构体的内存对齐方式默认为按4字节对齐,这意味着结构体中的每个成员都会按照4字节的倍数分配内存空间。

但是,有时候按4字节对齐会造成浪费,因为有些数据类型只需要1字节或2字节的内存空间就可以表示。

所以,我们可以使用#pragma pack来修改结构体的内存对齐方式。

例如,如果我们想要按1字节对齐,只需要在结构体定义前加上#pragma pack(1)即可。

pragma pack(1)struct student{char name[20];int age;char gender;float score;};在这个例子中,我们定义了一个学生结构体,其中成员name为字符串类型,占用20字节;age为int类型,占用4字节;gender为char类型,占用1字节;score为float类型,占用4字节。

因为我们使用了#pragma pack(1),所以这个结构体会按照1字节对齐方式来分配内存空间,最终占用的空间大小为29字节。

需要注意的是,尽管按照1字节对齐可以节省大量的内存空间,但是也会影响程序的运行效率。

因为按照1字节对齐会增加内存读写操作的次数,导致程序运行速度变慢。

因此,在定义结构体时,我们需要根据实际情况来选择适合的内存对齐方式。

如果对内存空间非常敏感,可以考虑按照1字节对齐方式;如果对性能要求比较高,可以选择按照4字节或8字节对齐。

在实际编程中,我们可以使用调试工具来观察各种对齐方式的内存占用情况,以便更好地选择内存对齐方式,从而优化程序性能和内存占用。

malloc 对齐算法

malloc 对齐算法

malloc 对齐算法malloc对齐算法一、引言在C语言中,动态内存分配是非常常见的操作。

我们使用malloc 函数来动态分配内存。

然而,由于计算机存储器的特性,malloc函数返回的内存地址并不总是按照我们期望的方式对齐。

为了提高内存访问的效率,我们需要对malloc返回的内存地址进行对齐操作。

本文将介绍malloc对齐算法及其原理。

二、对齐的概念对齐是指内存地址按照一定规则对齐到某个特定值的过程。

在计算机系统中,对齐是为了提高内存访问的效率。

对齐的规则常见的有字节对齐、字对齐、双字对齐等。

对齐的基本原则是,数据的起始地址必须是数据类型大小的整数倍。

三、malloc函数的对齐问题malloc函数是C语言中用来动态分配内存的函数。

它的函数原型为:void *malloc(size_t size);malloc函数返回的内存地址并不总是按照我们期望的方式对齐。

这是因为malloc函数返回的内存地址是根据系统的内存分配算法来确定的,而不是我们自己指定的。

四、malloc对齐算法的实现为了解决malloc函数返回的内存地址对齐的问题,我们可以使用一些技巧来实现对齐。

下面是一种常见的对齐算法:1. 首先,我们需要计算出对齐后的内存地址。

2. 然后,我们需要计算出需要分配的内存大小。

3. 接着,我们使用malloc函数分配内存。

4. 最后,我们需要将返回的内存地址进行对齐操作。

具体的对齐操作可以使用位运算来实现。

假设我们要将内存地址对齐到n字节,那么我们可以使用以下的位运算公式:aligned_addr = (addr + n - 1) & ~(n - 1);其中,aligned_addr是对齐后的内存地址,addr是原始的内存地址,n是对齐的字节数。

五、示例代码下面是一个示例代码,演示了如何使用malloc对齐算法对内存地址进行对齐操作。

```c#include <stdio.h>#include <stdlib.h>void* aligned_malloc(size_t size, size_t alignment) {void* ptr = malloc(size + alignment - 1);if (ptr == NULL) {return NULL;}void* aligned_ptr = (void*)(((size_t)ptr + alignment - 1) & ~(alignment - 1));return aligned_ptr;}int main() {int* p = aligned_malloc(100, 16);printf("Aligned address: %p\n", p);free(p);return 0;}```在上述示例代码中,我们定义了一个aligned_malloc函数,它接受两个参数:size和alignment。

C语言字节对齐__align()讲解

C语言字节对齐__align()讲解
五、什么时候需要设置对齐
在设计不同 CPU 下的通信协议时,或者编写硬件驱动程序时寄存器的结构这两个地 方都需要按一字节对齐。即使看起来本来就自然对齐的也要使其对齐,以免不同的编译器生 成的代码不一样.
一、快速理解 1. 什么是字节对齐? 在 C 语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如 int、long、 float 等)的变量,也可以是一些复合数据类型(如数组、结构、联合等)的数据单元。在 结构中,编译器为结构的每个成员按其自然边界(alignment)分配空间。各个成员按照它 们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。 为了使 CPU 能够对变量进行快速的访问,变量的起始地址应该具有某些特性,即所谓的”对 齐”. 比如4字节的 int 型,其起始地址应该位于4字节的边界上,即起始地址能够被4整除. 2. 字节对齐有什么作用? 字节对齐的作用不仅是便于 cpu 快速访问,同时合理的利用字节对齐可以有效地节省存储空 间。 对于32位机来说,4字节对齐能够使 cpu 访问速度提高,比如说一个 long 类型的变量,如果 跨越了4字节边界存储,那么 cpu 要读取两次,这样效率就低了。但是在32位机中使用1字节 或者2字节对齐,反而会使变量访问速度降低。所以这要考虑处理器类型,另外还得考虑编 译器的类型。在 vc 中默认是4字节对齐的,GNU gcc 也是默认4字节对齐。 3. 更改 C 编译器的缺省字节对齐方式 在缺省情况下,C 编译器为每一个变量或是数据单元按其自然对界条件分配空间。一般地, 可以通过下面的方法来改变缺省的对界条件: · 使用伪指令#pragma pack (n),C 编译器将按照 n 个字节对齐。 · 使用伪指令#pragma pack (),取消自定义字节对齐方式。 另外,还有如下的一种方式: · __attribute((aligned (n))),让所作用的结构成员对齐在 n 字节自然边界上。如果结 构中有成员的长度大于 n,则按照最大成员的长度来对齐。 · __attribute__ ((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数 进行对齐。 4. 举例说明 例1 struct test { char x1; short x2; float x3; char x4; }; 由于编译器默认情况下会对这个 struct 作自然边界(有人说“自然对界”我觉得边界更顺 口)对齐,结构的第一个成员 x1,其偏移地址为0,占据了第1个字节。第二个成员 x2为 short 类型,其起始地址必须2字节对界,因此,编译器在 x2和 x1之间填充了一个空字节。结构的 第三个成员 x3和第四个成员 x4恰好落在其自然边界地址上,在它们前面不需要额外的填充 字节。在 test 结构中,成员 x3要求4字节对界,是该结构所有成员中要求的最大边界单元, 因而 test 结构的自然对界条件为4字节,编译器在成员 x4后面填充了3个空字节。整个结构 所占据空间为12字节。 例2 #pragma pack(1) //让编译器对这个结构作1字节对齐

c语言4字节对齐指令

c语言4字节对齐指令

C语言4字节对齐指令一、什么是对齐指令1.1 对齐的概念在计算机中,对齐是指数据在内存中存储的方式。

内存中的数据是以字节为单位进行存储的,而对齐就是数据在内存中存储时的起始位置需要与其自身的大小对齐。

1.2 对齐的优势对齐的目的是为了提高计算机的访问速度。

当数据对齐之后,CPU的访问操作会更加高效,从而提高程序的执行效率。

二、数据对齐的原则数据的对齐有一定的规则,其中最常见的是按照字节对齐的原则进行排列。

2.1 字节对齐原则在C语言中,数据的字节对齐原则是根据数据类型的大小来确定的。

一般来说,对于基本数据类型,其对齐规则如下所示:•char类型不需要对齐,可以从任意位置开始存储。

•short类型需要2字节对齐,即起始地址必须是2的倍数。

•int类型需要4字节对齐,即起始地址必须是4的倍数。

•long类型需要8字节对齐,即起始地址必须是8的倍数。

2.2 结构体对齐原则对于结构体中的成员变量,其对齐规则也是按照字节对齐的原则进行排列的。

结构体中的成员变量按照其自身的大小顺序存放,并且每个成员变量的起始地址需要满足对齐规则。

三、C语言的对齐指令C语言提供了一些对齐指令,可以用来控制数据的对齐方式。

对齐指令可以通过编译器的选项来设置,也可以使用特殊的关键字进行设置。

3.1 编译器选项设置对齐方式编译器提供了一些选项来设置数据的对齐方式,其中最常用的是-malign-double 选项。

该选项可以控制double类型的对齐方式,一般情况下,我们可以将其设置为-malign-double=8,表示使用8字节对齐方式。

3.2 结构体的对齐指令在C语言中,可以使用#pragma pack(n)指令来设置结构体的对齐方式。

其中n表示对齐的字节数,常用的值为1、2、4、8等。

3.3 成员变量的对齐指令对于结构体中的某个成员变量,可以使用__attribute__((aligned(n)))指令来单独设置其对齐方式,其中n表示对齐的字节数。

字节对齐(强制对齐以及自然对齐)

字节对齐(强制对齐以及自然对齐)

字节对齐(强制对齐以及⾃然对齐)struct {}node;32为的x86,window下VC下sizeof(node)的值为1,⽽linux的gcc下值为0;⼀、WINDOWS下(VC--其实GCC和其原理基本⼀样,象这种问题,⼀般要查具体的编译器设置)字节对齐的规则:1、⼀般设置的对齐⽅式为1,2,4字节对齐⽅式,VC⼀般默认为4字节(最⼤为8字节)。

结构的⾸地址必须是结构内最宽类型的整数倍地址;另外,结构体的每⼀个成员起始地址必须是⾃⾝类型⼤⼩的整数倍(需要特别注意的是windows下是这样的,但在linux的gcc编译器下最⾼为4字节对齐),否则在前⼀类型后补0;这⾥特别提到的是数组⼀定要注意,⽽且在⼀些编程的技巧中,我们可以使⽤数组强制字节达到对齐的⽬的。

这在⽹络编程中是很常见的。

举例:⽐如CHAR型占⽤空间为1字节,则其起始位置必须可被1整除。

INT为4字节,其起始位置必须被4带队,依次类推。

(我们假定类或结构体的起始位置为0位置,其实编译器是在开辟空间时,会寻找起始位置可被结构内最宽类型整除的地址做为开始地址,因此我们可以假定其为0值,因为这0值可以被任意的类型整除。

)2、结构体的整体⼤⼩必须可被对齐值整除,默认4(默认,且结构中的类型⼤⼩都⼩于默认的4)。

3、结构体的整体⼤⼩必须可被本结构内的最宽类型整除。

(其实和上⼀条是⼀样的,但这⾥独⽴出来,起注意作⽤。

⽐如结构体⾥的有DOUBLE,那么结构的⼤⼩最后必须可被8整除)注意:GCC不是这样,就是最⾼只能被4整除,它是个死的。

否则(2、3条),编译器会在结构的最后添充⼀定的特定字符来补齐。

struct T{char ch;double d ;};在VC中是16个字节,GCC中为12个字节。

4、对于结构体内嵌套结构体的形势,规定是必须按照基本数据类型来定义,⽽不能以嵌套结构⼤⼩来做为上三种使⽤的基准。

⼆、举例:struct A{int a;char b;short c;};struct B{char b;int a;short c;};struct C{double t;char b;int a;short c;};struct D{char b;double t;int a;short c;};在VC中,SIZEOF这四个结构体,分别为:8、12、24、24;我们先谈第⼀个,(说明⼀下,在考虑结构体⼤⼩时,我们基本可以忽略起始地址的问题,因为这个编译器会⾃动为我们做好,见上⾯的说明),结构体内⾸先是⼀个INT的4字节,起始地址假定为0,整除4,其⼩于等于默认的4字节对齐且0为4(INT的占⽤空间)的整数倍,所以,其占四个字节;其后为起始地址为5,空间为1个字节的CHAR,⼩于4且5为1(CHAR占⽤空间)的整数倍,故占⽤1个字节,然后是⼀个起始地址为5占2个字节的SHORT,其⼩于4,但5不为2的整数倍,故补齐⼀个字节,从第6个字节开始,占2字节空间。

c 8字节对齐 算法

c 8字节对齐 算法

c 8字节对齐算法在C语言中,8字节对齐通常是指将数据结构的每个成员按照8字节的边界进行对齐。

这样可以提高数据访问的效率,因为CPU通常以固定大小的数据块(比如4字节或8字节)进行数据访问。

一种常见的算法用于确定数据结构中每个成员的对齐方式,称为对齐算法。

对齐算法通常根据数据类型的大小和所需的内存对齐边界来确定每个成员的对齐方式。

下面是一个简单的对齐算法示例,用于计算一个结构体中每个成员的对齐方式:c#include <stdio.h>#include <stdint.h>typedef struct {uint32_t a; // 4 bytes aligneduint64_t b; // 8 bytes alignedfloat c; // 4 bytes alignedchar d[12]; // 12 bytes aligned} MyStruct;int main() {printf("Size of MyStruct: %lu bytes\n", sizeof(MyStruct));printf("Offset of a: %lu bytes\n", offsetof(MyStruct, a));printf("Offset of b: %lu bytes\n", offsetof(MyStruct, b));printf("Offset of c: %lu bytes\n", offsetof(MyStruct, c));printf("Offset of d: %lu bytes\n", offsetof(MyStruct, d));return 0;}在这个例子中,我们定义了一个名为MyStruct的结构体,其中包含四个成员变量:a、b、c和d。

每个成员变量的类型不同,因此它们的大小和对齐方式也不同。

字节对齐作用

字节对齐作用

字节对齐作用字节对齐作用什么是字节对齐字节对齐是一种数据存储方式,用于提高计算机内存的读取效率。

在计算机中,数据被存储为字节的形式,每个字节有固定的大小。

字节对齐的原理计算机在读取数据时,通常以字节为单位进行操作。

为了提高读取效率,计算机会将数据按照一定规则进行对齐。

字节对齐的原理是按照数据类型的大小,将数据存储在内存中的地址按照一定规则进行调整,使得数据可以更快地被读取和处理。

字节对齐的作用字节对齐在计算机中具有重要的作用,主要体现在以下几个方面:•提高读取效率:字节对齐可以减少对内存的读取次数,提高读取效率。

当数据按照自然边界对齐时,可以通过一次读取多个字节,减少读取的次数,提高数据读取的效率。

•节省存储空间:字节对齐可以减少内存空间的浪费。

当数据按照对齐规则进行对齐时,可以利用内存中的空闲字节,避免空间的浪费,节省存储空间。

•确保数据的连续存储:字节对齐可以保证数据在内存中的连续存储,减少内存碎片的产生。

当数据按照对齐规则进行对齐时,可以确保数据之间没有空隙,避免内存碎片的产生,提高内存的利用率。

•增加数据的可移植性:字节对齐可以增加数据的可移植性。

不同的计算机体系结构对字节对齐的要求可能不同,通过字节对齐可以保证数据在不同的计算机上都可以正确地读取和处理。

字节对齐的规则字节对齐的规则取决于具体的编程语言和计算机体系结构。

在C语言中,常用的字节对齐规则是按照数据类型的大小进行对齐,即数据类型的长度必须是其对齐要求的整数倍。

具体的对齐规则可以通过编译器的选项或者编程语言的特定语法进行设置和控制。

以下是常见的对齐规则:•对齐到自然边界:数据类型按照自身的大小进行对齐。

例如,一个int类型的数据通常按照4字节对齐。

•对齐到指定边界:数据类型按照指定的边界进行对齐。

例如,一个结构体可以通过设置#pragma pack(n)指令,将其对齐到n字节的边界。

•默认对齐规则:编译器根据具体的体系结构和编译选项进行对齐。

c语言字节对齐规则

c语言字节对齐规则

c语言字节对齐规则
C语言字节对齐规则是程序员在进行内存分配和结构体定义时需要遵守的一些规则。

这些规则是由编译器制定的,用于保证内存对齐,提高程序的执行效率。

下面列举一些常见的C语言字节对齐规则:
1. 对齐原则:结构体变量的起始地址必须是其最宽基本类型成员大小的倍数,也就是说,结构体变量的大小必须是其成员大小的倍数。

2. 数据成员对齐规则:结构体中的每个成员都按照其自身的大小进行对齐,例如char类型的成员对齐于1字节边界,int类型的成员对齐于4字节边界。

3. 结构体对齐规则:结构体中的成员按照其定义顺序进行排列,如果前面的成员已经对齐,但是后面的成员因为大小不同而无法对齐时,编译器会在前面的成员后面插入一些填充字节,以保证后面的成员能够对齐。

4. 结构体嵌套对齐规则:结构体中嵌套的结构体也需要进行对齐,对齐原则同上。

5. 指针对齐规则:指针的大小为4字节或8字节,根据机器的位数而定。

指针变量的对齐方式与其所指向的数据类型相同。

6. 最大对齐原则:结构体的最大对齐值为其成员中的最大对齐值,也就是说,结构体的对齐值不能超过其成员中的最大对齐值。

以上就是C语言字节对齐规则的一些常见内容。

理解和遵守这些规则可以提高程序的执行效率,减少内存的浪费,从而使程序更加高效。

C语言数据存储对齐详解

C语言数据存储对齐详解

struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B;sizeof( A)=6, sizeof( B)=8,为什么?注:sizeof(short)=2,sizeof(long)=4因为:“成员对齐有一个重要的条件,即每个成员按自己的方式对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里默认是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节.”(引用)结构体A中有3个short类型变量,各自以2字节对齐,结构体对齐参数按默认的8字节对齐,则a1,a2,a3都取2字节对齐,则sizeof(A)为6,其也是2的整数倍;B中a1为4字节对齐,a2为2字节对齐,结构体默认对齐参数为8,则a1取4字节对齐,a2取2字节对齐,结构体大小6字节,6不为4的整数倍,补空字节,增到8时,符合所有条件,则sizeof(B)为8;可以设置成对齐的#pragma pack(1)#pragma pack(push)#pragma pack(1)struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B;#pragma pack(pop) 结果为sizeof( A)=6,sizeof( B)=6************************2,又如:#pragma pack(8)struct S1{long b;};struct S2 {char c;struct S1 d;long long e;};#pragma pack()sizeof(S2)结果为24.成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐.也就是说上面虽然指定了按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字节对齐)整除.这样, 一共使用了24个字节.a bS1的内存布局:1***, 1111,c S1.a S1.b eS2的内存布局:1***, 1***, 1111, ****11111111这里有三点很重要:1.每个成员分别按自己的方式对齐,并能最小化长度2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐补充一下,对于数组,比如:char a[3];这种,它的对齐方式和分别写3个char是一样的.也就是说它还是按1个字节对齐. 如果写: typedef char Array3[3];Array3这种类型的对齐方式还是按1个字节对齐,而不是按它的长度.不论类型是什么,对齐的边界一定是1,2,4,8,16,32,64....中的一个./***********************/字节对齐详解为什么要对齐?现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。

c语言结构体按1字节对齐

c语言结构体按1字节对齐

c语言结构体按1字节对齐一、介绍在C语言中,结构体是一种用户自定义的数据类型,可以将多个不同类型的变量组合在一起,形成一个新的数据类型。

结构体的内存对齐是指如何在内存中布置结构体的成员变量,以提高内存的访问效率和存储空间利用率。

本文将深入探讨C语言结构体按1字节对齐的原理和用法。

二、结构体的对齐规则默认情况下,C语言中的结构体按照成员变量的数据类型和在结构体中的位置进行对齐,以提高内存的访问效率。

对齐原则是尽量使得结构体的每个成员变量的地址是其自身大小的整数倍。

C语言中的对齐规则通常是按照编译器的要求进行的,不同编译器可能有不同的对齐规则。

在大多数情况下,结构体的对齐规则遵循以下原则:1.结构体的起始地址必须是其最宽基本类型成员的整数倍。

2.结构体的大小必须是其最宽基本类型成员大小的整数倍。

3.结构体的成员变量在内存中的偏移量必须是其数据类型大小的整数倍。

三、C语言结构体按1字节对齐的方法通常情况下,编译器会使用默认的对齐规则来对结构体进行对齐。

但有时候,我们需要手动指定结构体按照1字节进行对齐,以满足特定的需求,比如与硬件设备的通信或数据的序列化和反序列化操作等。

在C语言中,可以使用预处理指令#pragma pack(n)来指定对齐字节数,其中n表示对齐字节数,可以为1、2、4、8等。

下面是使用#pragma pack(1)指定结构体按1字节对齐的示例:#pragma pack(1)struct example {char a;int b;short c;};#pragma pack()在上述示例中,#pragma pack(1)指定结构体example按照1字节进行对齐,即成员变量之间不进行任何对齐操作。

通过#pragma pack()将对齐方式恢复为编译器默认的对齐方式。

四、C语言结构体按1字节对齐的注意事项使用#pragma pack(1)指定结构体按照1字节进行对齐可以满足特定需求,但也需要注意一些细节问题,以防止出现访问错误、内存泄漏等问题。

c语言 字节对齐问题造成复位

c语言 字节对齐问题造成复位

c语言字节对齐问题造成复位在C语言中,字节对齐是一个与硬件体系结构和编译器实现相关的概念。

字节对齐是指结构体中成员变量的存储地址相对于结构体的起始地址的偏移量必须是成员变量大小的整数倍。

字节对齐的问题可能导致结构体的大小变得比成员变量的总大小更大,这可能会对内存布局和访问产生影响,特别是在涉及到硬件寄存器、外设寄存器、或者与硬件通信的情况下。

考虑以下示例:#include <stdio.h>struct Example {char a; // 1字节int b; // 4字节char c; // 1字节};int main() {printf("Size of struct: %lu bytes\n", sizeof(struct Example));return 0;在这个例子中,由于字节对齐的原因,struct Example 的大小可能会大于 1 + 4 + 1 = 6 字节。

实际上,由于对齐,struct Example 的大小可能是8字节,这取决于编译器和编译器的配置。

为了解决这个问题,你可以使用编译器特定的指令来指定对齐方式。

在一些编译器中,可以使用 #pragma pack 指令。

例如,在GCC 中,可以这样使用:#pragma pack(push, 1)struct Example {char a; // 1字节int b; // 4字节char c; // 1字节};#pragma pack(pop)这个指令告诉编译器按照1字节的对齐方式来布局结构体。

但需要注意的是,这可能会导致性能下降,因为对齐的结构体在某些架构上的访问速度可能会变慢。

在解决字节对齐问题时,最好的做法是了解并理解你的编译器和目标体系结构的默认对齐方式,并根据实际需求进行适当的优化。

结构体字节对齐的作用

结构体字节对齐的作用

结构体字节对齐的作用简介字节对齐(byte alignment)是计算机体系结构中非常重要的概念之一。

在C语言中,结构体(struct)是一种数据类型,用于组合多个不同类型的变量。

结构体的字节对齐机制决定了结构体中各个成员变量在内存中的存放位置,从而影响了内存的使用效率、存储器的占用和程序的执行效率。

字节对齐的原因计算机内存的访问是按字节(byte)进行的,而不是按位(bit)进行的。

因此,为了提高内存的读取速度和写入速度,每个变量在内存中都需要按照一定的规则进行存放,这就是字节对齐的原因。

字节对齐的规则在C语言中,字节对齐的规则遵循以下几个原则:1.结构体的起始地址必须是该结构体中最大类型成员的整数倍。

也就是说,结构体的首地址必须满足对齐要求。

2.结构体中的每个成员变量的偏移量(相对于结构体首地址的偏移量)必须是该成员类型大小的整数倍。

3.结构体的总大小必须是该结构体中最大类型成员大小的整数倍。

字节对齐的作用字节对齐的主要作用是优化内存的使用效率和存储器的占用。

这是由于字节对齐规则决定了结构体中成员变量的存放位置,从而影响了结构体大小和成员变量的访问速度。

以下是字节对齐的具体作用:1.提高内存读取和写入速度:字节对齐可以使结构体成员变量在内存中的存放位置对齐,这样在访问结构体成员时,可以一次性读取或写入多个连续的字节,提高了内存操作的效率。

2.减少内存碎片:字节对齐可以减少内存碎片的产生。

如果结构体的成员变量没有按照字节对齐的规则进行存放,就会出现内存碎片,导致存储器的浪费。

3.提高缓存的命中率:在计算机体系结构中,存在多级缓存(Cache)用于加速数据的读取和写入操作。

通过合理地进行字节对齐,可以提高缓存的命中率,减少缓存失效带来的性能损失。

4.优化程序的执行效率:字节对齐可以减少内存的访问次数,从而提高程序的执行效率。

特别是在对结构体进行频繁的读写操作时,字节对齐能够明显地提升程序的性能。

判断字节字节对齐的原理

判断字节字节对齐的原理

判断字节字节对齐的原理字节对齐是计算机存储中的一个重要概念,它决定了数据在内存中的存储方式。

字节对齐的原理是为了提高计算机的存取效率和数据传输速度,同时也有助于解决硬件访问冲突的问题。

本文将详细介绍字节对齐的原理及其作用。

我们来了解一下字节对齐的概念。

字节对齐是指数据在内存中的存储位置必须是某个特定值的整数倍。

在计算机中,数据是以字节为单位进行存储的,每个字节通常由8个二进制位组成。

字节对齐要求数据的存储起始地址必须是特定值的整数倍,这个特定值称为对齐单位。

对于不同的数据类型,其对齐单位可以是不同的。

为了更好地理解字节对齐的原理,我们以一个结构体为例进行说明。

假设有一个结构体如下:```cstruct Student {char name[20];int age;float score;};```在内存中,结构体的存储是连续的,每个成员的存储位置是相邻的。

但是,由于不同数据类型的对齐单位不同,结构体的字节对齐会影响成员的存储位置。

以常见的32位操作系统为例,假设对齐单位为4字节,则结构体的字节对齐规则如下:1. char类型的对齐单位为1字节,所以name数组的起始地址为结构体的起始地址。

2. int类型的对齐单位为4字节,由于name数组占用了20字节,不是4字节的整数倍,所以需要在name数组后面填充3个字节,以保证int类型的对齐要求。

因此,age的起始地址为结构体的起始地址+20。

3. float类型的对齐单位为4字节,由于age是int类型,已经满足了4字节对齐要求,所以score的起始地址为结构体的起始地址+20+4=24。

通过字节对齐,可以保证结构体的成员存储方式满足硬件的要求,提高了计算机的存取效率和数据传输速度。

此外,字节对齐还能够解决硬件访问冲突的问题。

由于计算机内存的访问通常是按字节进行的,如果数据存储位置不满足对齐要求,就会导致数据的跨字节读取或写入,增加了数据访问的复杂度和时间消耗。

c语言字节对齐规则

c语言字节对齐规则

c语言字节对齐规则
C语言字节对齐规则
字节对齐(Byte Alignment)是指内存地址和数据类型中字节的排列位置,由于内存地址以字节为单位进行分配,数据类型却有特定的字节内存空间,所以为了让数据类型跟内存地址对齐,就必须让数据类型的内存空间按照一定的对齐规则进行排列,这样才能让数据类型最小的内存空间能得到最优的分配。

C语言的字节对齐规则
1、C语言中,结构体的属性是以字节为单位进行分配的。

2、对于大小为1字节的变量,不管在结构体的哪个位置,都不会进行字节对齐,一个变量一个字节就是一个字节,不会增加其他字节的占用。

3、对于大小为2字节的变量,要求其在结构体的位置为偶数,将会对其右边多出一个字节的占用,但是不会多出一个字节的内存,只是在内存的右边多出一个字节的位置而已。

4、对于大小为4字节的变量,要求其在结构体的位置为4的倍数,也会对其右边多出三个字节的占用,但是不会多出三个字节的内存,只是在内存的右边多出三个字节的位置而已。

5、对于大小为8字节的变量,要求其在结构体的位置为8的倍数,也会对其右边多出七个字节的占用,但是不会多出七个字节的内存,只是在内存的右边多出七个字节的位置而已。

6、C中的枚举常量和指针类型都会进行字节对齐,枚举常量和
指针类型都会被当做int类型来对齐,即按照4个字节的方式对齐。

7、C语言中,数组也会进行字节对齐,但是这里需要根据该数组的元素的大小来决定字节对齐的规则,如果数组的元素大小是1字节,则不进行字节对齐;如果是2字节,则按照2字节对齐规则进行字节对齐;如果数组的元素大小是4字节,则按照4字节的对齐规则进行字节对齐;如果大于4字节,则按照8字节的对齐规则进行字节对齐。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

c++内存中字节对齐问题详解一、什么是字节对齐,为什么要对齐?现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。

对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。

一些平台对某些特定类型的数据只能从某些特定地址开始存取。

比如有些架构的CPU 在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。

比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。

显然在读取效率上下降很多。

二、请看下面的结构:struct MyStruct{double dda1;char dda;int type};对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少呢?也许你会这样求:sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13但是当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为16。

你知道为什么在VC中会得出这样一个结果吗?其实,这是VC对变量存储的一个特殊处理。

为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理。

在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。

下面列出常用类型的对齐方式(vc6.0,32位系统)。

类型对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)Char偏移量必须为sizeof(char)即1的倍数int偏移量必须为sizeof(int)即4的倍数float偏移量必须为sizeof(float)即4的倍数double偏移量必须为sizeof(double)即8的倍数Short偏移量必须为sizeof(short)即2的倍数各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。

同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。

下面用前面的例子来说明VC到底怎么样来存放结构的。

struct MyStruct{double dda1;char dda;int type};为上面的结构分配空间的时候,VC根据成员变量出现的顺序和对齐方式,先为第一个成员dda1分配空间,其起始地址跟结构的起始地址相同(刚好偏移量0刚好为sizeof(double)的倍数),该成员变量占用sizeof(double)=8个字节;接下来为第二个成员dda分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char)的倍数,所以把dda存放在偏移量为8的地方满足对齐方式,该成员变量占用sizeof(char)=1个字节;接下来为第三个成员type分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为9,不是sizeof (int)=4的倍数,为了满足对齐方式对偏移量的约束问题,VC自动填充3个字节(这三个字节没有放什么东西),这时下一个可以分配的地址对于结构的起始地址的偏移量为12,刚好是sizeof(int)=4的倍数,所以把type存放在偏移量为12的地方,该成员变量占用sizeof(int)=4个字节;这时整个结构的成员变量已经都分配了空间,总的占用的空间大小为:8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。

所以整个结构的大小为:sizeof(MyStruct)=8+1+ 3+4=16,其中有3个字节是VC自动填充的,没有放任何有意义的东西。

下面再举个例子,交换一下上面的MyStruct的成员变量的位置,使它变成下面的情况:struct MyStruct{char dda;double dda1;int type};这个结构占用的空间为多大呢?在VC6.0环境下,可以得到sizeof(MyStruc)为24。

结合上面提到的分配空间的一些原则,分析下VC怎么样为上面的结构分配空间的。

(简单说明)struct MyStruct{char dda;//偏移量为0,满足对齐方式,dda占用1个字节;double dda1;//下一个可用的地址的偏移量为1,不是sizeof(double)=8//的倍数,需要补足7个字节才能使偏移量变为8(满足对齐//方式),因此VC自动填充7个字节,dda1存放在偏移量为8//的地址上,它占用8个字节。

int type;//下一个可用的地址的偏移量为16,是sizeof(int)=4的倍//数,满足int的对齐方式,所以不需要VC自动填充,type存//放在偏移量为16的地址上,它占用4个字节。

};//所有成员变量都分配了空间,空间总的大小为1+7+8+4=20,不是结构//的节边界数(即结构中占用最大空间的类型所占用的字节数sizeof//(double)=8)的倍数,所以需要填充4个字节,以满足结构的大小为//sizeof(double)=8的倍数。

所以该结构总的大小为:sizeof(MyStruc)为1+7+8+4+4=24。

其中总的有7+4=11个字节是VC自动填充的,没有放任何有意义的东西。

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个字节。

这时已经为所有成员变量分配了空间,共分配了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()sizeof(S2)结果为24.成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐.也就是说上面虽然指定了按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字节对齐)整除.这样,一共使用了24个字节.a bS1的内存布局:11**,1111,c S1.a S1.b dS2的内存布局:1***,11**,1111,****11111111这里有三点很重要:1.每个成员分别按自己的方式对齐,并能最小化长度。

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

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

相关文档
最新文档