当前位置: 首页 > news >正文

内存对齐规则


在没有#pragma pack宏的情况下,内存对齐的规则如下:

规则1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。

规则2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

规则3:收尾工作,结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍.不足的要补齐.

规则1示例:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    struct A{
        int *a;
        short b;
        int c;
        char d;
        float e;
        double f;
    };
    struct A a;
    printf("0x%x [0,1,2,3]\n",&a.a);
    printf("0x%x [4,5]\n",&a.b);
    printf("0x%x [8,9,10,11] 规则1\n",&a.c);
    printf("0x%x [12]\n",&a.d);
    printf("0x%x [16,17,18,19] 规则1\n",&a.e);
    printf("0x%x [24,25,26,27,28,29,30,31]\n",&a.f);
    printf("%d\n",sizeof(struct A));
    return 0;
}


规则2示例:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    struct B{
        char a;
        int b;
    };
    struct A{
        int *a;
        short b;
        struct B b1;
        int c;
        char d;
        float e;
        double f;
    };
    struct A a;
    printf("0x%x [0,1,2,3]\n",&a.a);
    printf("0x%x [4,5]\n",&a.b);
    printf("0x%x [8] 规则2\n",&a.b1.a);
    printf("0x%x [12,13,14,15]\n",&a.b1.b);
    printf("0x%x [16,17,18,19] 规则1\n",&a.c);
    printf("0x%x [20]\n",&a.d);
    printf("0x%x [24,25,26,27] 规则1\n",&a.e);
    printf("0x%x [32,33,34,35,36,37,38,39]\n",&a.f);
    printf("%d\n",sizeof(struct A));
    return 0;
}


规则3示例:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    struct A{
        short a;
        double b;
    };
    struct A a;
    printf("0x%x [0,1]\n",&a.a);
    printf("0x%x [8,9,10,11,12,13,14,15] 规则1\n",&a.b);
    printf("%d 规则3\n",sizeof(struct A));
    return 0;
}


使用#pragam pack(n)更改编译默认的对齐方式:

规则4:告诉编译器,所有的对齐按照min(n,当前成员的大小)的整数倍进行对齐。

规则5:收尾工作,结构体的总大小,也就是sizeof的结果,必须是min(n,其内部最大成员的大小)的整数倍.不足的要补齐.

#include <stdio.h>
#include <stdlib.h>

#pragma pack(4)

int main(int argc, char *argv[])
{
    struct A{
        short a;
        short b;
        double c;
    };
    struct A a;
    printf("0x%x [0,1]\n",&a.a);
    printf("0x%x [2,3] 规则4\n",&a.b);
    printf("0x%x [4,5,6,7,8,9,10,11] 规则4\n",&a.c);
    printf("%d 规则5\n",sizeof(struct A));
    return 0;
}


参考:http://blog.csdn.net/hairetz/article/details/4084088


相关文章:

  • 【Deep Learning学习笔记】Deep learning for nlp without magic_Bengio_ppt_acl2012
  • 不用外部JAR包,自己实现JSP文件上传!
  • 计算机技术不是吓唬大众的工具!
  • Windows程序设计学习笔记--第一个Windows程序以及宽字符集(了解)
  • 云计算和大数据入门
  • Windows Azure使用必读
  • Windows Azure新功能:Hadoop和Web版的移动服务
  • 云计算的理解
  • 微软云存储SkyDrive API:将你的数据连接到任何应用、任何平台,及任何设备上...
  • 在 Windows Azure 上部署预配置 Oracle VM
  • 对于Visual Studio 2013中 Blend的HTML开发人员来说什么是新的
  • 微软云服务获政府认证 云服务或将迎来黄金期
  • SAE 搭建 WordPress
  • 自定义 WordPress 样式
  • 比较了一下基于PhoneGAP/JQ Mobile 等基于HTML5的Phone 开发框架
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • httpie使用详解
  • JAVA_NIO系列——Channel和Buffer详解
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • java中的hashCode
  • js学习笔记
  • Lsb图片隐写
  • MobX
  • mongodb--安装和初步使用教程
  • Python中eval与exec的使用及区别
  • V4L2视频输入框架概述
  • 安卓应用性能调试和优化经验分享
  • 什么软件可以剪辑音乐?
  • 学习JavaScript数据结构与算法 — 树
  • 源码安装memcached和php memcache扩展
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • ###C语言程序设计-----C语言学习(3)#
  • #define
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (ZT)出版业改革:该死的死,该生的生
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (力扣)1314.矩阵区域和
  • (论文阅读40-45)图像描述1
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .NET Framework杂记
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .net 简单实现MD5
  • .net/c# memcached 获取所有缓存键(keys)
  • .netcore如何运行环境安装到Linux服务器
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .sh文件怎么运行_创建优化的Go镜像文件以及踩过的坑
  • [ Linux 长征路第二篇] 基本指令head,tail,date,cal,find,grep,zip,tar,bc,unname
  • [ vulhub漏洞复现篇 ] Celery <4.0 Redis未授权访问+Pickle反序列化利用