为了让CPU能够更舒服地访问到变量,struct中的各成员变量的存储地址有一套对齐的机制。
这个机制概括起来有两点:
第一,每个成员变量的首地址,必须是它的类型的对齐值的整数倍,如果不满足,它与前一个成员变量之间要填充(padding)一些无意义的字节来满足;
第二,整个struct的大小,必须是该struct中所有成员的类型中对齐值最大者的整数倍,如果不满足,在最后一个成员后面填充。
各种类型的变量的align值如下,参考的是wikipedia的页面:
----------------------------------------------------------------------------------------
Data structure alignment
The following typical alignments are valid -bit x86:
A -byte aligned.
A -byte aligned.
An -byte aligned.
A -byte aligned.
A --byte aligned on Linux.
A -byte aligned on Linux.
Any pointer (four bytes) will be -byte aligned on Linux. (eg: char*, int*)
The only notable difference -bit linux system when compared to a bit is:
A -byte aligned.
A -byte aligned.
Any pointer (eight bytes) will be -byte aligned.
----------------------------------------------------------------------------------------
这里写了个程序来验证这些事:
#include <stdio.h>

struct s {
char a;
short b;
char c;
double d;
char e;
};

int main() {

struct s s1;

printf("%d, %d, %d, %d, %d\n",
(char*)(&s1.a) - (char*)(&s1),
(char*)(&s1.b) - (char*)(&s1),
(char*)(&s1.c) - (char*)(&s1),
(char*)(&s1.d) - (char*)(&s1),
(char*)(&s1.e) - (char*)(&s1));
printf("%d\n", sizeof(struct s));

;
}

在64位linux下面运行这段代码的结果是:

, , , ,

由于对齐机制的存在,实际上上面的struct在内存中是长这个样子的,共计24个字节:
查看源代码
打印帮助
struct s {
char a; //在地址为0的位置
]; //由于下面一个元素是short,对齐字节数为2的位数,需要补1字节
short b; //对齐到了地址为2的位置
char c; //在地址为4的位置
]; //由于下面一个元素是double,对齐字节数为8的倍数,需要补3字节
double d; //对齐到了地址为8的位置
char e; //在地址为16的位置
]; //整个struct的大小需要是对齐数最大者,也就是double的8字节的整数倍
};
       ____________________________________________________________________________________________
       |       |////////|         |         |              |                |        |            |
       |   a   |padding1|    b    |    c    |    padding2  |        d       |    e   |padding3    |
       |       |////////|         |         |              |                |        |            |
       +------------------------------------------------------------------------------------------+
 Bytes:    1        1        2          1            3            8            1            7
如果是在32位的linux下跑上面的程序,由于double的长度还是8字节,但是对齐是4字节的了,所以前面几个成员的位置不变,
而最后的padding只需要补3个字节就可以了,所以输出的结果是0, , , , 16及20.
对于windows,其32位和64位下double都是8字节对齐的,所以在32位和64位下跑这个程序结果都是0, , , , 16及24.
最后,整个struct的大小的要求是对齐值最大者的整数倍,没有什么默认的4或者8的倍数一说。如果把上面程序中的a,b,c,d,e的
类型全变成char,那么最后的他们的地址会是0,,,,,整个struct的大小 sizeof(struct s)的值是5,没有任何padding发生。
以上程序实验的环境在64位centos x64上的gcc (32位结果加-m32参数)及Visual Studio 2008上得出。

c语言中struct的内存对齐的更多相关文章

  1. Net的struct的内存对齐问题

    很少有人谈起struct的内存对齐问题, 就是在很多C#书中, 也很少提及. 但在实际应用中, 如果不注意内存对齐, struct比较大的话, 则会浪费一定的内存.    先从一个实例看起. publ ...

  2. C 语言结构体 struct 及内存对齐

    struct 结构体 对于复杂的数据类型(例如学生.汽车等),C 语言允许我们将多种数据封装到一起,构成新类型. 跟面向对象语言中的对象相比,结构体只能包含成员变量,不支持操作. #include & ...

  3. c语言中struct的初始化

    C++中的struct已经和class一样,可以用构造函数初始化. C语言中的struct怎么初始化呢? typedef struct _TEST_T {        int i;        c ...

  4. C语言中 struct成员变量顺序对内存的占用

    在C语言的结构体中,是会按照其变量类型来进行分配内存大小的.但是对于不同的编译器,结果是不同的,在VC++6.0中是怎么个分配情况呢?用一下C中的关键字sizeof()来测试下,注意sizeof()不 ...

  5. C struct的内存对齐

    说明:如果你看到了这篇,请略过. struct是复合类型. 其中的成员在内存中的分布都是对齐的. 这个对齐的意思是,struct的sizeof运算结果必定是其最大类型长度的整数倍. --注意,如果st ...

  6. C语言中struct位域的定义和使用

    位域的定义和使用 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又 ...

  7. 内存对齐-C语言struct内存占用问题

    转1个写的比较全面的. http://hubingforever.blog.163.com/blog/static/17104057920122256134681/ 本文编辑整理自:http://hi ...

  8. struct内存对齐1:gcc与VC的差别

    struct内存对齐:gcc与VC的差别 内存对齐是编译器为了便于CPU快速访问而采用的一项技术,对于不同的编译器有不同的处理方法. Win32平台下的微软VC编译器在默认情况下采用如下的对齐规则:  ...

  9. 【转】C/C++ struct/class/union内存对齐

    原文链接:http://www.cnblogs.com/Miranda-lym/p/5197805.html struct/class/union内存对齐原则有四个: 1).数据成员对齐规则:结构(s ...

随机推荐

  1. 织梦(Dedecms) 5.1 feedback_js.php 注入漏洞

    漏洞版本: DEDECMS 5.1 漏洞描述: 同样是在magic_quotes_gpc=off的情况下可用 此漏洞可拿到后台管理员的帐号和加密HASH,漏洞存在文件plus/feedback_js. ...

  2. 设备树(Device Tree)

    设备树介绍: 设备树是一个描述设备硬件资源的文件,该文件是由节点组成的树形结构.如下: / { node1 { a-string-property = "A string"; a- ...

  3. WeifenLuo.WinFormsUI.Docking添加关闭功能

    /****************************************************************** * 创建人:HTL * 创建时间:2014-7-8 15:37: ...

  4. Cognos如何开启CJAP认证程序日志

    步骤: 1:修改ipfaaaclientconfig.xml.sample为ipfclientconfig.xml,修改<param name="File" value=&q ...

  5. 统计的一个小题目python实现

    最近面试碰到的一个题目,业余时间用python实现的. 拿到数据,先用sort 命令排序,也可再进一步去重复 sort -k 1,2  data.txt |uniq  > data.new # ...

  6. Thinkpad X201 Gobi2000 上电信3G网络

    网上的教程大多有点小问题,许多都不完整,今天放出系统化.理论化的设置方法,附送上所有软件. 一.本教程适用范围:1.gobi 2000 正式版 FRU:60Y3263 (带MEID.IMEI)2.- ...

  7. 【性能测试】Linux性能监控命令——sar详解

    转载:https://blog.csdn.net/mig_davidli/article/details/52149993 sar命令可以从文件的读写情况.系统调用的使用情况.磁盘I/O.CPU效率. ...

  8. angularjs中的$eval方法

    在controller中定义了一个变量 $scope.a_1 = "abc"; 想在view里面动态输出,因为这个数字是动态的,这么输出肯定是不行的{{'a_' + '1'}},因 ...

  9. java在线预览txt、word、ppt、execel,pdf代码

    在页面上显示各种文档中的内容.在servlet中的逻辑 word: BufferedInputStream bis = null; URL url = null; HttpURLConnection ...

  10. Python 访问dict

    访问dict 1:可以if判断元素是否存在 2:dict.get('key')我们已经能创建一个dict,用于表示名字和成绩的对应关系:d = { 'Adam': 95, 'Lisa': 85, 'B ...