#pragma pack 定义变量的起始存放地址对齐方式

pack用来指定变量在内存中的存放起始地址对齐方式;

具体用法如下:

1 #pragma pack(push,n) // 保存当前系统设置的对齐方式,压入堆栈,然后设置当前对齐方式为n字节对齐,n通常取 1 2 4 8
2
3 .........
4
5 #pragma pack(pop) // 恢复当前的对齐方式

pack对齐方式:选当前数据类型本身占用字节数与pack指定的对齐字节数两者之间的最小值, 用这个最小值的整数倍作为存放的起始地址。

例1:

1 #pragma pack(push,4)
2 typedef struct test
3 {
4     char j;
5     short x;
6     int i;
7 }node;

此时char本身是单字节变量,pack是按照4字节对齐,这两者之间最小值是1,故按照1字节的倍数算起始地址存放变量j,存放在内存 ram[0]中,j占用1个字节;

下一个元素short x 本身是2字节的变量,pack是4字节对齐,按照取这两者中最小数的倍数做起始地址,所以取2的倍数做起始地址放short x,上一个元素char占用了0地址,只占用了单个字节,2的倍数只能是char再填充一个值后再存放short x,故short x 从ram[2]开始存,占用2字节;

int i本身占用4字节,pack要求4字节对齐,故只要满足存放的起始地址是4的倍数即可,前面2个元素分别占用了ram[0]-ram[3],故int i从ram[4]开始算起始地址,往后存放4字节。

所以这个结构体总共占用8字节。

例2:

#pragma pack(push,2)
typedef struct test
{
    char j;
    short x;
    int i;
}node;

这个结构体也是占用8字节

char本身是单字节变量,pack要求2字节对齐,取这两者中最小值的整数倍做起始地址,故取1的最小整数倍做起始地址存放char j,存放在ram[0],占用1个字节;

short x本身是双字节变量,pack要求2字节对齐,故只要是2的整数倍就可以做为起始地址,前面的变量只占用了ram[0]空间,ram[1]不是2的整数倍,所以取下一个地址ram[2]作为存放起始地址,short x存放于ram[2]-ram[3]占用2字节

int i本身是4字节变量,pack要求2字节对齐,故只要是2的整数倍就可以作为起始存放地址,ram[4]正好是2的整数倍,故存放在ram[4]-ram[7]共占用4字节。

时间: 2024-08-25 05:57:51

#pragma pack 定义变量的起始存放地址对齐方式的相关文章

C语言结构体变量内存分配与地址对齐

地址对齐简单来说就是为了提高访问内存的速度. 数组的地址分配比较简单,由于数据类型相同,地址对齐是一件自然而然的事情. 结构体由于存在不同基本数据类型的组合,所以地址对齐存在不同情况,但总体来说有以下规则: 原则1:数据成员对齐规则:结构的数据成员,第一个数据成员放在偏移量(offset)为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储). 原则2:收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大

释析#pragma pack(push,n) #pragma pack(n) #pragma pack() #pragma pack(pop)

今天阅读别人写得的代码时,发现了#pragma pack(n) 这段代码,不知道加这个代码是什么个意思,然后自己就查了一下资料,然后写了段代码试了试,还有点那么个意思, 含义是:告诉编译器设置结构体的边界字节对齐方式,也就是所有数据在内存中是存储的方式. 这句话挺模糊的, 我们接下来先看几个例子程序, 例子一 struct weikangc { int nAge; char cSex; }; int main(int argc, char* argv[]) { printf("%d\r\n&qu

关于结构体占用空间大小总结(#pragma pack的使用)

关于C/C++中结构体变量占用内存大小的问题,之前一直以为把这个问题搞清楚了,今天看到一道题,发现之前的想法完全是错误的.这道题是这样的: 在32位机器上,下面的代码中 class A { public: int i; union U { char buff[13]; int i; }u; void foo(){} typedef char* (*f)(void*); enum{red , green, blue}color; }a; sizeof(a)的值是多少?如果在代码前面加上#pragm

转载: #pragma pack(push,1) & #pragma pack(pop)

1 引子 在程序中,有的时候我们定义结构体的时候,要用#pragma pack(push,1) & #pragma pack(pop)类似代码将结构体包起来. 一般形式如下: #pragma pack(push,1): struct A { } : #pragma pack(pop): 这么做有什么目的呢? 注:下列内容来自网络. 2 #pragma pack简介 #pragma pack是指定数据在内存中的对齐方式, 在 C语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如in

字节对齐#pragma pack

这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式. #pragma pack (n)             作用:C编译器将按照n个字节对齐.#pragma pack ()               作用:取消自定义字节对齐方式. #pragma  pack (push,1)     作用:是指把原来对齐方式设置压栈,并设新的对齐方式设置为一个字节对齐 #pragma pack(pop)            作用:恢复对齐状态 因

#pragma pack(push) 和#pragma pack(pop) 以及#pragma pack()

我们知道结构体内存对齐字节可以通过#pragma pack(n) 的方式来指定. 但是,有没有想过一个问题,某些时候我想4字节对齐,有些时候我又想1字节或者8字节对齐,那么怎么解决这个问题呢? 此时,#pragma pack(push) 和#pragma pack(pop) 以及#pragma pack()应运而生. 看测试代码:(说明,64位GCC,默认8字节对齐) 屏蔽了的代码选别看,只看这个结构体,在默认8字节对齐的方式下,sizeof大小为24个字节,这不再做分析,之前随笔分析过了. 然

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_

#pragma pack(push,1)与#pragma pack(1)的区别(转)

这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式. #pragma pack (n)             作用:C编译器将按照n个字节对齐.#pragma pack ()               作用:取消自定义字节对齐方式. #pragma  pack (push,1)     作用:是指把原来对齐方式设置压栈,并设新的对齐方式设置为一个字节对齐 #pragma pack(pop)            作用:恢复对齐状态 因

#pragma pack(n)

内存对齐原则 1.  对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(#pragma pack()指定的数,这个数据成员的自身长度) 的倍数. 2.  在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行. #pragma pack(n)表示默认以n字节对齐,若某变量(如int)的字节大于n,则以n的倍数对齐. A: ---- ---- B: ----