• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 深入理解C语言内存对齐

深入理解C语言内存对齐

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c语言内存分配,c语言内存四区,c语言内存对齐,c语言内存泄漏,c语言内存溢出等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

一.内存对齐的初步讲解

内存对齐可以用一句话来概括:

“数据项只能存储在地址是数据项大小的整数倍的内存位置上”

例如int类型占用4个字节,地址只能在0,4,8等位置上。

例1:

int main()
{
        struct xx bb;
        printf("&a = %p/n", &bb.a);
        printf("&b = %p/n", &bb.b);
        printf("&c = %p/n", &bb.c);
        printf("&d = %p/n", &bb.d);
        printf("sizeof(xx) = %d/n", sizeof(struct xx));

        return 0;
}
</div>
执行结果如下:

可以简单的修改结构体的结构,来降低内存的使用,例如可以将结构体定义为:

二.操作系统的默认对齐系数

每 个操作系统都有自己的默认内存对齐系数,如果是新版本的操作系统,默认对齐系数一般都是8,因为操作系统定义的最大类型存储单元就是8个字节,例如 long long(为什么一定要这样,在第三节会讲解),不存在超过8个字节的类型(例如int是4,char是1,long在32位编译时是4,64位编译时是 8)。当操作系统的默认对齐系数与第一节所讲的内存对齐的理论产生冲突时,以操作系统的对齐系数为基准。

例如:

假设操作系统的默认对齐系数是4,那么对与long long这个类型的变量就不满足第一节所说的,也就是说long long这种结构,可以存储在被4整除的位置上,也可以存储在被8整除的位置上。

可以通过#pragma pack()语句修改操作系统的默认对齐系数,编写程序的时候不建议修改默认对齐系数,在第三节会讲解原因

例2:

int main()
{
        struct xx bb;
        printf("&a = %p/n", &bb.a);
        printf("&b = %p/n", &bb.b);
        printf("&c = %p/n", &bb.c);
        printf("&d = %p/n", &bb.d);
        printf("sizeof(xx) = %d/n", sizeof(struct xx));

        return 0;
}
</div>
打印结果为:

三.内存对齐产生的原因

内存对齐是操作系统为了快速访问内存而采取的一种策略,简单来说,就是为了放置变量的二次访问。操作系统在访问内存 时,每次读取一定的长度(这个长度就是操作系统的默认对齐系数,或者是默认对齐系数的整数倍)。如果没有内存对齐时,为了读取一个变量是,会产生总线的二 次访问。

例如假设没有内存对齐,结构体xx的变量位置会出现如下情况:

这样大家就能理解为什么结构体的第一个变量,不管类型如何,都是能被8整除的吧(因为访问内存是从8的整数倍开始的,为了增加读取的效率)!

内存对齐的问题主要存在于理解struct等复合结构在内存中的分布。

首先要明白内存对齐的概念。
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。

这个k在不同的cpu平台下,不同的编译器下表现也有所不同。比如32位字长的计算机与16位字长的计算机。这个离我们有些远了。我们的开发主要涉及两大平台,windows和linux(unix),涉及的编译器也主要是microsoft编译器(如cl),和gcc。

内存对齐的目的是使各个基本数据类型的首地址为对应k的倍数,这是理解内存对齐方式的终极法宝。另外还要区分编译器的分别。明白了这两点基本上就能搞定所有内存对齐方面的问题。

不同编译器中的k:
1、对于microsoft的编译器,每种基本类型的大小即为这个k。大体上char类型为8,int为32,long为32,double为64。
2、对于linux下的gcc编译器,规定大小小于等于2的,k值为其大小,大于等于4的为4。

明白了以上的说明对struct等复合结构的内存分布就应该很清楚了。

下面看一下最简单的一个类型:struct中成员都为基本数据类型,例如:
};<

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 深入解析C语言中的内存分配相关问题
  • 模拟实现C语言中的内存管理
  • C语言获取消耗内存的方法
  • 深入理解C语言内存对齐
  • C语言中的内存泄露 怎样避免与检测

相关文章

  • 2017-05-28解析C语言中位字段内存分配的问题
  • 2017-05-28C语言 文件的随机读写详解及示例代码
  • 2017-05-28深入解析C++编程中类的封装特性
  • 2017-05-28哈夫曼算法构造代码
  • 2017-05-28关于c++ 智能指针及 循环引用的问题
  • 2017-05-28C++实现获取IP、子网掩码、网关、DNS等本机网络参数的方法
  • 2017-05-28浅谈时间戳与日期时间互转C语言
  • 2017-05-28C++读写INI配置文件的类实例
  • 2017-05-28c++通过引用实现三个数字求最大值
  • 2017-05-28C/C++回调函数介绍

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C++ explicit关键字的应用方法详细讲解
    • C语言实现获取内存信息并输出的实例
    • 深入uCOS中全局变量的使用详解
    • 探讨:用两个栈实现一个队列(我作为面试官的小结)
    • win32使用openfilename浏览文件窗口示例
    • 详解C语言中的错误报告errno与其相关应用方法
    • C++中用栈来判断括号字符串匹配问题的实现方法
    • 详解C语言结构体中的函数指针
    • C++设计模式之命令模式
    • C语言 以数据块的形式读写文件详解及实现代码

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有