C语言详解热门考点结构体内存对齐

目录
  • 一、为什么存在内存对齐
  • 二、如何计算?(考点)
  • 三、手撕代码

一、为什么存在内存对齐

大部分的参考资料都是如是说的:

1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能再某些地址处取某些特定类型的数据,否则抛出硬件异常。

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

总体来说:结构体的内存对齐是拿空间来换取时间的做法

二、如何计算?(考点)

首先得掌握结构体得对齐规则:

1.第一个成员再与结构体变量偏移量为0得地址处。

2.其他成员变量要对齐到自身对齐数得整数倍得地址处。

  • 对齐数 = 编译器默认得一个对齐数 与 该成员大小的较小值 (VS中默认的值为8)

3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

三、手撕代码

上面的干货太干了是不是,小伙伴们可以多读几遍,结合下面练习把这块知识点拿下。

练习1:

struct s1
{
	char c1;
	int i;
	char c2;
};
printf("%d\n", sizeof(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; //0
	struct s3 s; //8-23
	double d; //24-31

	int i;
};
printf("%d\n", sizeof(struct s4));//32

这是嵌套结构体的情况,在内存中所占的每一位已标出(要32位,太多了就没画图哈哈)。谢谢大家耐心读到这里,如果这篇文章对你有所帮助,还请三连支持!

到此这篇关于C语言详解热门考点结构体内存对齐的文章就介绍到这了,更多相关C语言 内存对齐内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言热门考点结构体与内存对齐详解

    目录 一.引例 1.结构体的第一个成员永远放在结构体起始位置偏移量为0的位置 2.从第二个成员开始,总是放在偏移量为一个对齐数的整数处,对齐数=编译器默认的对齐数和变量自身大小的较小值 3.结构体的总大小必须是各个成员的对齐数中最大的那个对齐数的整数倍 二.小试牛刀 三.嵌套结构体的特殊情况 四.关于为什么存在内存对齐 1.平台原因(移植原因): 2.性能原因: 总结 一.引例 到底什么是结构体内存对齐,我们用一段代码来介绍一下 struct S1 { char c1;//1字节 int a;/

  • C语言结构体中内存对齐的问题理解

    目录 前言 思考 结构体在内存中开辟空间时内存对齐的规则 为什么存在内存对齐 1.平台的原因 2.性能的原因 前言 学C的同学应该知道~ 想精通C语言就不得不面对—指针与内存 续上次指针的进阶,这一章我来聊一聊C语言内存对齐的问题 学习结构体的你有没有注意过结构体向系统申请的内存为多少呢的 思考 #include<stdio.h> typedef struct s1 { char a; char b; int c; }s1; typedef struct s2 { char a; int c;

  • C语言 详细分析结构体的内存对齐

    目录 一.结构体 二.结构体内存对齐 1.非嵌套结构体的大小 2.含嵌套结构体的大小 三.为什么要内存对齐 1.平台原因(移植原因) 2.性能原因 一.结构体 结构体 (struct)是一种数据结构,可以包含很多数据类型,可以实现比较复杂的数据结构. 常见的int,char类型变量,我们可以一眼看出占多少字节,但对于结构体,可就有点难度了. 让我们来猜猜以下程序的输出 struct S1 { char c1; int i; char c2; }; struct S2 { char c1; cha

  • C语言中结构体、联合体的成员内存对齐情况

    前言 最近项目进行中,遇到一个小问题,在数据协议传输过程中,我为了方便解析,就定义了一个结构体,在数据的指针传入函数的时候,我用定义好的结构体进行强制转化,没想到一直解析失败,调试很久,终于反应过来,在用结构体指针对数据强制转换时,定义结构体我没有注意到数据对齐,因为在底层实现中,我传入的数据buffer是排列整齐的,而强制转化的结构体格式中,我定义的时候没有使用__attribute__((__packed__))或者__packed强制数据对齐,导致结构体成员真实排列会按照成员中最大的变量的

  • C语言中结构体与内存对齐实例解析

    1.结构体类型 C语言中的2种类型:原生类型和自定义类型,结构体类型是一种自定义类型. 2.结构体使用时先定义结构体类型再用类型定义变量 -> 结构体定义时需要先定义结构体类型,然后再用类型来定义变量. -> 也可以在定义结构体类型的同时定义结构体变量. // 定义类型 struct people { char name[20]; int age; }; // 定义类型的同时定义变量. struct student { char name[20]; int age; }s1; // 将类型st

  • C语言结构体内存对齐详解

    目录 实例一: 分析:存储结构图如下 实例二: 分析:存储结构如下 实例三: 分析:存储结构如下 实例四: 分析:存储结构图如下 总结 1.结构体内存对齐是指当我们创建一个结构体变量时,会向内存申请所需的空间,用来存储结构体成员的内容.我们可以将其理解为结构体成员会按照特定的规则来存储数据内容. 2.结构体的对齐规则 (1)第一个成员在相比于结构体变量存储起始位置偏移量为0的地址处. (2)从第二个成员开始,在其自身对齐数的整数倍开始存储(对齐数=编译器默认对齐数和成员字节大小的最小值,VS编译

  • C语言详解热门考点结构体内存对齐

    目录 一.为什么存在内存对齐 二.如何计算?(考点) 三.手撕代码 一.为什么存在内存对齐 大部分的参考资料都是如是说的: 1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的:某些硬件平台只能再某些地址处取某些特定类型的数据,否则抛出硬件异常. 2.性能原因:数据结构(尤其是栈)应该尽可能地再自然边界上对齐.原因在于,为了访问未对其的内存,处理器需要作两次内存访问:而对齐的内存访问仅需要一次访问. 总体来说:结构体的内存对齐是拿空间来换取时间的做法 二.如何计算?(考点)

  • C++面试题之结构体内存对齐计算问题总结大全

    前言 本文给大家介绍的是关于C++结构体内存对齐计算的相关内容,内存对齐计算可谓是笔试题的必考题,但是如何按照计算原则算出正确答案一开始也不是很容易的事,所以专门通过例子来复习下关于结构体内存对齐的计算问题.话不多说,来一起看看详细介绍吧. 编译环境:vs2015 对齐原则: 原则1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个

  • c++ 结构体内存对齐基本概念及示例

    基本概念: 各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数, 各成员变量在存放的时候根据在结构中出现的顺序依次申请空间 同时按照上面的对齐方式调整位置. 空缺的字节自动填充, 同时为了确保结构的大小为结构的字节边界数(即该结构中占用最大的空间的类型的字节数)的倍数,所以在为最后一个成员变量申请空间后 还会根据需要自动填充空缺的字节: 举例说明: #include <iostream> using namespace std; #pragma pack

  • C语言结构体内存的对齐知识详解

    前言 在前面的章节中,我们谈到了C语言中整数以及浮点数的储存 今天,我们来谈一谈一些关于结构体内存的知识. 我们先来看一个例子: struct S1 { char c1; int i; char c2; }; 大家来猜猜这个结构体S1的内存是多少? 相信会有人给出 6 的结果,他们或许是这样想的,两个 char 类型分别为一个字节,一个 int 类型又为4个字节,加起来刚好为6个 但是 结果真是如此吗? 我们来看看运行结果: 为什么呢,接下来我们就引出正文. 一.结构体内存对齐规则 首先,正如引

  • Go语言类型内嵌和结构体内嵌的具体使用

    目录 内嵌结构体 结构内嵌特性 结构体可以包含一个或多个匿名(或内嵌)字段,即这些字段没有显式的名字,只有字段的类型是必须的,此时类型也就是字段的名字.匿名字段本身可以是一个结构体类型,即结构体可以包含内嵌结构体. 可以粗略地将这个和面向对象语言中的继承概念相比较,随后将会看到它被用来模拟类似继承的行为.Go语言中的继承是通过内嵌或组合来实现的,所以可以说,在Go语言中,相比较于继承,组合更受青睐. 考虑如下的程序: package main import "fmt" type inn

  • 一文带你搞懂Golang结构体内存布局

    目录 前言 结构体内存布局 结构体大小 内存对齐 总结 前言 结构体在Go语言中是一个很重要的部分,在项目中会经常用到,大家在写Go时有没有注意过,一个struct所占的空间不一定等于各个字段加起来的空间之和,甚至有时候把字段的顺序调整一下,struct的所占空间不一样,接下来通过这篇文章来看一下结构体在内存中是怎么分布的?通过对内存布局的了解,可以帮助我们写出更优质的代码.感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助. 结构体内存布局 结构体大小 结构体实际上就是由各种类型的数据组合而成

  • C语言详解结构体的内存对齐与大小计算

    目录 结构体的内存对齐 1.计算结构体的大小 2.结构体的对齐规则 3.为什么存在内存对齐? 4.总结 结构体的内存对齐 1.计算结构体的大小 struct S1 { char c1; // 1 byte,默认对齐数为8,所以c1的对齐数是1,第一个成员变量放在与结构体变量偏移量为0的地址处 int i; // 4 byte,默认对齐数为8,所以i的对齐数是4,所以i要放到偏移量为 4的整数倍 的地址处 char c2; // 1 byte,默认对齐数为8,所以c2的对齐数是1,所以c2要放到偏

  • C++结构体字节对齐和共用体大小

    目录 1.结构体内存对齐 2.共用体的内存大小 3.枚举的大小 1.结构体内存对齐 结构体内存对齐在笔试和面试中经常被问到,所以做个总结 通过代码验证不同结构体的内存大小: #include <stdio.h> struct Node1{ char c1; int val1; char c2; }; struct Node2{ char c1; char c2; int val1; }; struct Node3{ char c1; char array[10]; }; struct Node

随机推荐