返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言重难点之内存对齐和位段
  • 689
分享到

C语言重难点之内存对齐和位段

2024-04-02 19:04:59 689人浏览 独家记忆
摘要

一:结构体内存对齐 (1)为什么要存在内存对齐 平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些平台只能在某些地址处取得某些特定类型的数据,否则抛出硬件

一:结构体内存对齐

(1)为什么要存在内存对齐

平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些平台只能在某些地址处取得某些特定类型的数据,否则抛出硬件异常。
比如,当一个平台要取一个整型数据时只能在地址为4的倍数的位置取得,那么这时就需要内存对齐,否则无法访问到该整型数据。

性能原因:
数据结构(尤其是栈)应该尽可能的在自然边界上对齐。原因在于,为了访问未对齐内存,处理器需要作两次内存访问;而对齐的内存访问仅需一次。

核心思想就是:以空间换取时间

 举个例子:对于有32根地址总线的计算机来说,每次读取的单位是4个字节,假入定义了如下结构体:


struct s1
{
char c1;
int i;
char c2;
}

由于c1占1个字节,i占4个字节,c2占1个字节,所以计算机在读取时候,会先读取c1和i的3个字节(共四个字节)、再读取i的最后一个字节和c2。因此计算器不但需要进行两次内存读取,并且还需要对i的数据进行拼接,无形中浪费了运行的时间。所以为了减少时间的浪费,就采用了内存对齐的方式。

(2)结构体对齐规则

  • 第一个成员在与结构体变量偏移量为0的地址处。(即结构体的首地址处,即对齐到0处)
  • 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
  • 结构体的总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
  • 如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

其中对齐数=编译器默认的一个对齐数与该成员大小的较小值。vs中默认为8。linux中默认值为4。

(3)结构体对齐演示

以下面的构体为例


struct S
{
	double d;
	char c;
	int i;
};

第一步:把结构体中每个成员变量的大小与编译器的默认对齐数进行比较,取小的作为该成员的对齐数

在这里插入图片描述

第二步:从0位开始,画出这些成员的位置,注意对齐到自己的对齐数

在这里插入图片描述

故为16个字节

(4)练习


//练习1
struct S1{
	char c1;
	int i;
	char c2;
};
printf("%d\n", printf(struct S1);//12

//练习2 
struct S2 {
    char c1;    
    char c2;    
    int i; 
 }; 
 printf("%d\n", sizeof(struct S2));//8

//练习3 
struct S3 {
    double d;    
    char c;    
    int i; 
}; 
printf("%d\n", sizeof(struct S3));//16

//练习4-结构体嵌套问题 
struct S4 {
    char c1;    
    struct S3 s3;    
    double d; 
}; 
printf("%d\n", sizeof(struct S4));//32

二:位段

(1)什么是位段

“节省空间”这四个字可以直截了当的点名位段的作用。

在结构体设计中,我们一般用int来存年龄这样的数据,但是年龄这个东西再大也不会达到几百几千,也就是它的范围一般是1-100,反应在整形数据的内存上,使用的可能就是32个比特位中的个别几个,也就说剩余的很多比特位就是根本不会用到的,而如果明知道这样,还要不管三七二十一直接抛出一个整形,四个字节,32个比特位存储这么小的数,未免显的有点浪费了。所以正式鉴于此,位段就能合理的进行内存设计

(2)位段怎么写

位段的基本格式如下,和结构体十分相似,其内部的数据类型一般要求是一致的

在这里插入图片描述

(3)位段结构体对齐怎么算

上述这个结构体所占空间大小为八个字节,在实际分配时,会一上来先分配四个字节,其中a,b,c占据2+5+10共17个比特位,剩余d需要30个比特位存储但是不够,所以再分配四个字节,拿出其中30个比特位存储。可以看出相比之前暴力的直接16个字节,现在的8个字节大大的节省了空间。

再比如下面位段


struct A
{
	unsigned a : 19;
	unsigned b : 11;
	unsigned c : 4;
	unsigned d : 29;	
	char index;
};

其中a和b共占据4个字节,c和d占据八个字节,index对齐对齐1个字节,最终就是16

 位段的跨平台问题

  • int 位段被当成有符号数还是无符号数是不确定的。
  • 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机
  • 器会出问题。
  • 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
  • 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

到此这篇关于C语言重难点之内存对齐和位段的文章就介绍到这了,更多相关C语言 内存对齐和位段内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C语言重难点之内存对齐和位段

本文链接: https://lsjlt.com/news/125617.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C语言重难点之内存对齐和位段
    一:结构体内存对齐 (1)为什么要存在内存对齐 平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些平台只能在某些地址处取得某些特定类型的数据,否则抛出硬件...
    99+
    2024-04-02
  • C语言重难点之内存对齐和位段的示例分析
    这篇文章主要介绍了C语言重难点之内存对齐和位段的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。C语言是什么C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于...
    99+
    2023-06-15
  • C语言详解热门考点结构体内存对齐
    目录一、为什么存在内存对齐二、如何计算?(考点)三、手撕代码一、为什么存在内存对齐         大...
    99+
    2024-04-02
  • C语言结构体内存对齐详解
    目录实例一:分析:存储结构图如下实例二: 分析:存储结构如下实例三:  分析:存储结构如下 实例四:分析:存储结构图如下总结1、结构体内存对齐...
    99+
    2024-04-02
  • C语言热门考点结构体与内存对齐详解
    目录一、引例二、小试牛刀三、嵌套结构体的特殊情况四、关于为什么存在内存对齐1.平台原因(移植原因): 2.性能原因: 总结一、引例 到底什么是结构体内存对齐,我们用一段代码来介绍一下...
    99+
    2024-04-02
  • C语言中结构体怎么与内存对齐
    本篇内容介绍了“C语言中结构体怎么与内存对齐”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.结构体类型C语言中的2种类型:原生类型和自定义...
    99+
    2023-06-20
  • 一篇文章带你了解C语言内存对齐
    目录内存对齐三、在内存对齐话题下的sizeof与offsetof宏3.1、sizeof3.2、offsetof宏3.3、Debug总结内存对齐 先看如下代码: 结构体Test1...
    99+
    2024-04-02
  • C语言详细分析结构体的内存对齐
    目录一.结构体二.结构体内存对齐1.非嵌套结构体的大小2.含嵌套结构体的大小三.为什么要内存对齐1.平台原因(移植原因)2.性能原因一.结构体 结构体 (struct)是一种数据结构...
    99+
    2024-04-02
  • C语言中结构体与内存对齐的方法
    这篇文章主要介绍了C语言中结构体与内存对齐的方法的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C语言中结构体与内存对齐的方法文章都会有所收获,下面我们一起来看看吧。1.结构体类...
    99+
    2024-04-02
  • C语言中结构体与内存对齐实例解析
    1.结构体类型 C语言中的2种类型:原生类型和自定义类型,结构体类型是一种自定义类型。 2.结构体使用时先定义结构体类型再用类型定义变量 -> 结构体定义时需要先定义结构体类型...
    99+
    2024-04-02
  • C语言结构体中内存对齐的问题理解
    目录前言思考结构体在内存中开辟空间时内存对齐的规则为什么存在内存对齐1.平台的原因2.性能的原因前言 学C的同学应该知道~ 想精通C语言就不得不面对—指针与内存 续上次指...
    99+
    2024-04-02
  • C语言中结构体的内存对齐规则讲解
    目录1.结构体的内存对齐规则2.例子3.为什么存在内存对齐4.如何修改默认对齐数1.结构体的内存对齐规则 1.第一个成员在与结构体变量偏移量为0的地址处。 2.其他成员变量都放在对齐...
    99+
    2024-04-02
  • C语言程序中结构体的内存对齐详解
    目录一、为什么存在内存对齐二、结构体的内存对齐四规则三、举例一、为什么存在内存对齐 1.平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某...
    99+
    2022-11-13
    C语言结构体内存对齐 C语言 内存对齐 C语言 结构体
  • 一篇文章带你了解C语言内存对齐公式
    目录一、前言二、公式2.1、例子一2.2、例子二2.3、例子三总结一、前言 每一个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。GCC中默认#program pack...
    99+
    2024-04-02
  • C语言详细分析结构体的内存对齐规则
    目录引例结构体内存对齐规则那么为什么要有内存对齐呢如何优化修改默认对齐数结构体的内存对齐是一个特别热门的知识点! 引例 #include<iostream> using ...
    99+
    2024-04-02
  • C语言详解结构体的内存对齐与大小计算
    目录结构体的内存对齐1、计算结构体的大小2、结构体的对齐规则3、为什么存在内存对齐?4、总结结构体的内存对齐 1、计算结构体的大小 struct S1 { char c1; // ...
    99+
    2024-04-02
  • C语言结构体的内存对齐与大小怎么计算
    这篇文章主要讲解了“C语言结构体的内存对齐与大小怎么计算”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言结构体的内存对齐与大小怎么计算”吧!结构体的内存对齐1、计算结构体的大小struc...
    99+
    2023-06-30
  • C语言中结构体、联合体的成员内存对齐情况
    前言 最近项目进行中,遇到一个小问题,在数据协议传输过程中,我为了方便解析,就定义了一个结构体,在数据的指针传入函数的时候,我用定义好的结构体进行强制转化,没想到一直解析失败,调试很...
    99+
    2024-04-02
  • C语言可变参数与函数参数的内存对齐详解
    目录什么是可变参数?使用可变参数函数参数的内存对齐总结什么是可变参数? 有时,您可能会碰到这样的情况,您希望函数带有可变数量的参数,而不是预定义数量的参数。 C 语言为这种情况提供了...
    99+
    2024-04-02
  • 一篇文章带你了解C语言内存对齐解决的问题
    目录一、内存对齐为4个字节的好处二、内存对齐的目的是以空间换取速度2.1、内存对齐为4的例子2.2、内存没有使用内存对齐的例子CPU读取数据的过程:三、掌握内存对齐的必要性总结一、内...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作