结构体字节对齐,pragma pack,__attribute__(packed)

程序编译器对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏   蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。

例如我们设置结构体的对齐方式:

struct student

{

int age;

char c;

};

对于以上结构体,默认用sizeof输出大小为8字节,默认的字节对齐方式是4,当然我们也可以设置他的对齐   方式,如下:

#pragma pack(2) //(或 pragma(push,4))

struct student

{

int age,

char c;

};

#pragma pack(pop) //注意这个和push是成对用的

此时用sizeof输出大小是为6,因为对齐方式为2.如果设置对齐方式为1的话,sizeof输出大小则为5;

当然有时我们不希望编译器对结构体做对齐处理,而希望按照他原有的大小分配空间,这里就要用到  __attribute__((packed)) ,这个意思是告诉编译器不要做对齐处理。

struct Student

{

int age;

char c;

}__attribute__((packed));

int main()

{

struct Student S;

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

}

输出大小为 5,其实和一字节对齐方式一样。


到这里可能许多人和我刚开始一样不理解这个__attribute__((packed)) 是个什么东东,这个其实是GUN C   的一大特色,是一种机制,他可以设置函数属性,变量属性,类型属性,packed就是个类型属性。

   当然__attribute__还可以用来设置字节对齐属性。

   __attribute__((aligned(4)));设置4字节对齐方式,和#pragma pack(4) 效果一样,我的总结大概就是这   些,希望对大家有用,么么哒。

#include <stdio.h>
 
 
typedef struct Student_t
{
	int age;
	char c;
}__attribute__((packed)) Student;
 
typedef struct Node_t
{
	int a;
	char c;
}__attribute__((aligned(4))) Node;
 
#pragma pack(push,1)
typedef struct List_t
{
	int a;
	char c;
}List;
#pragma pack(pop)
 
int main()
{
	Node A;
	List B;
	Student C;
	printf("%d,%d,%d\n",sizeof(A),sizeof(B),sizeof(C));
	return 0;
}
输出大小依次为:5,8,5


写到这里顺便再补充一下,通常在跨平台的基于数据结构的网络通信的时候特别要注意字节的对齐方式,以为在不同的系统中,某些类型的大小不一样。

              short       int    long       long long          ptr     time_t
     32位           2         4       4             8               4        4
     64位           2         4       8             8               8        8

在定义通信用的结构体时,应该考虑使用定常的数据类型,如uint32_t,4字节的固定长度,并且这属于标准C库(C99),在各系统中都可使用。


猜你喜欢

转载自blog.csdn.net/huangyimo/article/details/80929878