转载--结构对齐

转载 2007年09月17日 00:18:00
关于C语言中的结构体对齐问题
1,比如:

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{
    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      b
S1的内存布局:1***, 1111,
                          c      S1.a    S1.b             e
S2的内存布局: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....中的一个.

转自:http://blog.chinaunix.net/u/11768/showart.php?id=70557

一道关于结构对齐的题目
struct{
        short a1;
        short a2;
        short a3;
}A;
struct{
        long a1;
        short a2;
}B;
问:为什么sizeof(A)为6,sizeof(B)为8。
这是一个关于结构数据对齐的题,其原因是为了加快CPU的存取速度,编译器在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,叫数据对齐(data alignment)。其对齐规则为:结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节。这也就是为什么会出现这个现象的原因。因为sizeof(short)为2,sizeof(int)为4,sizeof(long)也为4。对于开头题目中的Struct B,因为long长为4,short长为2,因为short会补跳成为4,因此为8。而对于Strutc A,每个成员均为2,因此不需要补空字节。
下面另一个例子:
#include <stdio.h>

struct{
        short a1;
        short a2;
        short a3;
        long a4;
}A;
struct{
        long a1;
        int a3;
}B;
int main()
{
        printf("sizeof(short)=%d sizeof(long)=%d sizeof(int)=%d/n", sizeof(short), sizeof(long
), sizeof(int));
        printf("sizeof(A)=%d sizeof(B)=%d/n", sizeof(A), sizeof(B));
        return 0;
}
struct A长为12,因为a1和a2一起长度为4,a3为2,long为4,因为需要为a3补空字节,使其长度变为4。
Struct B长为8.
再看另一个结构:
struct{
        short a1;
        long a5;
        short a2;
        long a6;
        short a3;
        long a4;
}A;
其长度为24,因为a1长为2,a5长为4,因此a1需要补成4,其余字节同样。
但当我们把struct A调整为
struct{
        short a1;
        short a2;
        short a3;
        long a4;
        long a5;
        long a6;
}A;
其长度就变为20了。
说实在话,这个问题是我以前根本没注意的问题。
但是如果我们在前面加上#pragma pack(1),我们会发现编译不会进行对齐的操作。因为成员对齐有一个重要的条件,即每个成员按自己的方式对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节.”

[转载] sizeof()和结构对齐

本文主要包括二个部分,第一部分重点介绍在VC中,怎么样采用sizeof来求结构的大小,以及容易出现的问题,并给出解决问题的方法,第二部分总结出VC中sizeof的主要用法。1、 sizeof应用在结构...
  • DDGG
  • DDGG
  • 2008年05月12日 16:56
  • 1006

c结构体对齐深刻理解

最近在实习的公司,作为新人和其他的新人做了一个新人技术交流会,主要是关于C的一些基础知识,包括了C的编译,链接,指针,数组,字符串,结构体等,以及一些项目相关的知识,总的来说技术交流会还是很有用的,大...
  • w616589292
  • w616589292
  • 2016年03月18日 17:06
  • 1490

Mingw-gcc结构体取消对齐

在gcc中,一般是可以通过__attribute__((packed))属性来取消对齐的,昨天在写个小工具是发现在使用code::block+mingw-gcc时却是死活不行了,无奈之下,只有在虚拟机...
  • kuwater
  • kuwater
  • 2014年03月28日 14:56
  • 868

ARM处理器关于非对齐存储的访问规则

ARM 系列处理器是 RISC (Reducded Instruction Set Computing)处理器。很多基于ARM的高效代码的程序设计策略都源于RISC 处理器。和很多 RISC 处理...
  • j_akill
  • j_akill
  • 2014年01月03日 17:50
  • 1870

结构对齐

    个人草草总结没有充分验证:     没有任何限定是结构体各成员自然边界对齐(long,long long ,double 4 bytes 在arm 里 ),结构体本身按照其最大成员自然边界对齐...
  • Jeffoery
  • Jeffoery
  • 2009年04月08日 10:47
  • 85

C语言结构中的边界对齐问题

没错,今天2月14,单身狗如我情人节也只能苦逼地撸代码了。不知道大家有没有发现一个奇怪的现象,见图~ 结构test里面包含了1个int型变量和2个char型变量,照理说sizeof...
  • qq_37521235
  • qq_37521235
  • 2017年02月14日 23:56
  • 766

C/C++中的结构体对齐问题(内存对齐)

由于程序运行时占用的内存过大,所以想办法给程序瘦身。在调试中发现结构体占用的size竟然和预想的不一样,原来…… 看看下面讲的吧,肯定会不枉此看哦! 1,比如: struct{    short a1...
  • fyh2003
  • fyh2003
  • 2011年06月26日 19:50
  • 3921

vc struct的成员对齐

 1.struct的成员对齐:  #pragma pack (n) //n:1 2 4 8 16 1.1 自然对界     struct是一种复合数据类型,其构成元素既可以是基本数据类型(如int、l...
  • Daisy423XU
  • Daisy423XU
  • 2007年08月02日 15:28
  • 2325

C++成员对齐方式探讨

关于C++中结构体成员对齐的一点探讨。
  • znd8866
  • znd8866
  • 2014年04月20日 17:44
  • 745

VC6默认设置下结构体对齐大小

项目右键  --> Setting  --> C/C++ --> Code Grneration ,默认值为8 对齐原则:      原则1: 数据成员的对齐规则                ...
  • LDWJ2016
  • LDWJ2016
  • 2016年10月14日 10:08
  • 606
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:转载--结构对齐
举报原因:
原因补充:

(最多只允许输入30个字)