C++ 内存对齐 及 引用是否真的节省内存的一点思考

文章目录

    • 1. 内存对齐
    • 2. 递归中的内存对齐
    • 3. C++引用的本质
    • 4. 致谢

1. 内存对齐

通过以下语句,获取变量的占用内存打下:

cout << "size of int " << sizeof(int) << endl;
cout << "size of int& " << sizeof(int&) << endl;
cout << "size of char " << sizeof(char) << endl;

int 和 int& 都占 4 字节, char 占 1 字节

编写一个类:其包含1个 int,2个 char,排列顺序不同。

class memory1
{int id;char a;char b;
};
class memory2
{char a;int id;char b;
};
class memory3
{char a;char b;int id;
};

可以看见,他们的占用空间大小是不一样的。

size of memory1 8
size of memory2 12
size of memory3 8
  • 计算机从内存读取数据是按块读取的,一般是4或者8的倍数一块,一起读取
  • CPU和内存IO的硬件限制导致没办法将一个数据类型分在两个块中读取
  • 内存对齐,可以加快程序的运行速度,一般编译器会在后台进行内存对齐优化,但是也不能做到十分完美
  • 内存对齐的参数可以更改,#pragma pack(n),n = 1,2,4,8,16

所以上面的memory类的内存对齐是按照4字节进行的,计算机按照顺序分配内存,4字节剩余空间能放下某个类型的,就放进去,放不进去的,新往下找一块4字节的空间放 int

加入#pragma pack(1),可见就是紧密排列了。

size of memory1 6
size of memory2 6
size of memory3 6
#pragma pack(2)
size of memory1 6
size of memory2 8
size of memory3 6

2. 递归中的内存对齐

我在做LeetCode题的时候遇到一个递归爆栈问题:

在这里做一些测试,不保证结果具有通用性,也请大家指正。

void dfs(int i) {int k = 0;cout << "&k = " << &k << endl;cout << "i = " << i << endl;i = i+1;dfs(i);
}
int main() {int i = 0;dfs(i);
}

变更dfs(i)参数个数
递归次数:32385,第一个k的地址 0x61fdcc,k地址间隔 6410(参数个数为1-4个)


增加参数个数到(5-6个):
递归次数:25908,第一个k的地址 0x61fdbc(比上面移动了16),k地址间隔 8010
增加参数个数到(7-8个):
递归次数:21589,第一个k的地址 0x61fdac(比上面移动了32),k地址间隔 9610
增加参数个数到(9-10个):
递归次数:18505,第一个k的地址 0x61fd8c(比上面移动了64),k地址间隔 11210
增加参数个数到(11个):
递归次数:16191,第一个k的地址 0x61fd7c(比上面移动了80),k地址间隔 12810

增加参数个数到(10个,且全部改成&引用):
递归次数:18505,第一个k的地址 0x61fd8c(比上面移动了64),k地址间隔 11210
以上均为win1064位操作系统 环境


目前通过结果,可以看见,

  • 参数的增多,递归层数会减小
  • 递归中的栈也遵守内存对齐原则
  • int 型的 & 对递归深度没有造成影响(win10,64位)
class memory1
{int id;char a[1280];char b;
};
int main() {int i = 0;int j = 0;int a = 0, b = 0, c = 0,d=0,e=0,f=0,g=0,h=0,l=0;memory1 m1;dfs(m1,i, j, a, b,c,d,e,f,g,h);
}
size of memory1 1288

上面程序,

递归次数:1436,第一个k的地址 0x61f34c(比上面移动了2688),k地址间隔 144010

将 m1 改成&

cout << "size of memory1& " << sizeof(&m1) << endl;
size of memory1& 8

递归次数:16181,第一个k的地址 0x61f86c(比上面移动了1376),k地址间隔 12810

  • 对于大型 结构数据,采用&能大幅节省空间,递归不至于过早爆栈结束。

但是,上面 LeetCode 爆栈就只是把 int&改成int程序就不爆栈了,跟认知的规律是不符合的,还请大佬看看什么原因?

3. C++引用的本质

参考:c++中“引用”的底层实现原理详解
在读完上文后,就清楚了,引用会产生一个8字节的变量存储被引用的变量的地址,所以上面win10的测试结果,有点不可信,可能这就是C++在硬件、操作系统、编译器不同的情况下结果有差异的情况,采用 linux 进行测试

在linux中测试结果:

传入2个int: 递归次数174522
传入2个int&:递归次数130885
传入2个double: 递归次数130912
传入2个double&:递归次数104668

我想这个数值,已经能够侧面说明上面链接文章中提到的引用本质了,C++引用的本质是指针,但是它跟指针又不一样,C++对指针进行了封装产生了引用,你在使用引用的时候,传给你的是它里面指针所指向的内容。

所以对这种内置的变量类型,函数调用的时候,直接使用copy传入就可以了,还比较省内存(int 4字节,使用 int & 会占用 8字节)

至此,可以解释上面 LeetCode 那道题,传入 int & 爆栈了,而改为 int ,题目就AC通过了。

4. 致谢

感谢焦/huaix提出去掉&可以解决问题,开启了我对这个问题的思考
感谢Thin-k.调试,确认是stack-overflow的问题
感谢CSDN群里的朋友热心讨论和研究,还有论坛朋友akari10032的解答
感谢hitskyer阿福的答疑
感谢所有在网络上分享知识的每一个博主!

参考链接:
带你深入理解内存对齐最底层原理
C/C++内存对齐详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/476913.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小问题,对递归重复调用的改进,一起来分享

Problem设有一头小母牛&#xff0c;从出生第四年起每年生一头小母牛&#xff0c;按此规律&#xff0c;第N年时有几头母牛&#xff1f; Input本题有多组数据。每组数据只有一个整数N&#xff0c;独占一行。(1≤N≤50) Output对每组数据&#xff0c;输出一个整数&#xff08;独…

拦截游戏窗口被移动_Ruined King官网版-拳头rpg Ruined King游戏最新版下载v1.0

Ruined King是一款暗黑风格的动作冒险类手游&#xff0c;游戏采用回合制战斗方式为玩家进行呈现&#xff0c;多种强大的英雄需要玩家进行召集&#xff0c;大幅度提升角色的战斗力&#xff0c;丰富的任务等着玩家来完成&#xff0c;游戏中还有非常经典的剧情让玩家进行了解&…

AI开始卷高考了,英语已被卷到134分??

文 | 天于刀刀AI 真的太卷了&#xff01;不但模型之间互相卷&#xff0c;现在直接开始和人类学生一起卷高考了&#xff01;近期&#xff0c;来自 CMU 两位学者提出的重构预训练模型&#xff08;reStructured Pre-training, RST&#xff09;在只有 GPT-3 十六分之一参数量的情况…

(待解)静态构造器和静态字段调用的相互嵌套

示例代码&#xff1a;usingSystem;classA{ public static int X; static A() { X B.Y 1; }}classB{ public static int Y A.X 1; static B() {} static void Main() { Console.WriteLine("X {0}, Y {1}", A.X, B.Y); }}程序输出&#…

程序员面试金典 - 面试题 04.12. 求和路径(二叉树递归)

1. 题目 给定一棵二叉树&#xff0c;其中每个节点都含有一个整数数值(该值或正或负)。 设计一个算法&#xff0c;打印节点数值总和等于某个给定值的所有路径的数量。 注意&#xff0c;路径不一定非得从二叉树的根节点或叶节点开始或结束&#xff0c;但是其方向必须向下(只能…

一款三搭_冬日穿搭指南!照着这八条万能公式穿,让你不冻还有型_

就用我多年看搭配的经验为大家总结了8条万能公式&#xff01;想要做百岁老人的&#xff0c;冬天穿搭以下每一套都需要穿打底裤的哦&#xff01;&#xff01;&#xff01;公式一&#xff1a;大衣毛衣九分裤同色系袜子是画龙点睛之笔。同时大衣、毛衣和包包也是同色系&#xff0c…

pytorch可视化教程:训练过程+网络结构

文 | 锦恢知乎&#xff08;已授权&#xff09;源 | 极市平台一、网络结构的可视化我们训练神经网络时&#xff0c;除了随着step或者epoch观察损失函数的走势&#xff0c;从而建立对目前网络优化的基本认知外&#xff0c;也可以通过一些额外的可视化库来可视化我们的神经网络结构…

从今天起,开始等待中信世界杯信用卡

特喜欢卡面上克林斯曼凌空一脚的冲击性画面&#xff01;今早上填的申请表&#xff0c;工作人员说会在十四个工作日内答复。现在&#xff0c;作会梦先&#xff1a;&#xff09; 转载于:https://www.cnblogs.com/notus/archive/2006/06/14/425654.html

程序员面试金典 - 面试题 05.07. 配对交换(位运算)

1. 题目 配对交换。编写程序&#xff0c;交换某个整数的奇数位和偶数位&#xff0c;尽量使用较少的指令&#xff08;也就是说&#xff0c;位0与位1交换&#xff0c;位2与位3交换&#xff0c;以此类推&#xff09;。 示例1:输入&#xff1a;num 2&#xff08;或者0b10&#x…

亚马逊出的平板电脑_亚马逊推出了这款不到400元的平板电脑!学生党的福音!...

说到亚马逊&#xff0c;我们都知道Kindle&#xff0c;但亚马逊研发的电子产品可不止电纸书Kindle&#xff0c;或许很多小伙伴也听说过亚马逊的Kindle Fire 平板电脑&#xff01;亚马逊的平板电脑在国内或许不太出名&#xff0c;但在国外凭借着亚马逊强大的平台&#xff0c;Fire…

工作项跟踪管理系统需求

工作项跟踪管理系统需求 WIT &#xff08;Work Item Track&#xff09; 包含&#xff1a;缺陷跟踪、任务指派、突发事件处理、需求管理、客户定制 体现&#xff1a;流程性、规范性、流程可定制性 目的&#xff1a;帮助大家把工作做好、让工作更轻松、使得工作具有可管理性 …

程序员面试金典 - 面试题 08.03. 魔术索引(二分递归)

1. 题目 魔术索引。 在数组A[0…n-1]中&#xff0c;有所谓的魔术索引&#xff0c;满足条件A[i] i。 给定一个有序整数数组&#xff0c;编写一种方法找出魔术索引&#xff0c;若有的话&#xff0c;在数组A中找出一个魔术索引&#xff0c;如果没有&#xff0c;则返回-1。 若有…

Meta提出九头蛇注意力机制,比传统注意力快197倍,且准确率更高!

文 | 丰色 发自 凹非寺源 | 量子位尽管Transformer已经开始在诸多视觉任务上“大展身手”&#xff0c;但还有一个问题。那就是在处理大图像上计算比较费劲。比如面对一个1080p的图时&#xff0c;它会有超过60%的计算量都耗费在了创建和应用注意矩阵上。究其原因&#xff0c;主要…

怎么画单极交流放大电路波形图_区别在哪?:VCC、VDD、VEE、VSS、数字地、模拟地、信号地、交流地、直流地!...

【smt接单中】热烈祝贺张飞电子正式建成多条进口贴片加工流水线&#xff0c;下单送视频&#xff0c;狂优惠3个月&#xff01;&#xff01;&#xff01;张飞电子&#xff0c;smt加工&#xff0c;接单客服如下&#xff1a;客服小姐姐:笑笑 客服小姐姐:萌萌电话:18994463546 …

母版页(Master Pages)--轉載

母版页&#xff08;Master Pages&#xff09; http://blog.csdn.net/iiboy/  ASP.NET 1.x中最突出的缺点之一是它缺少对页面模板的支持。欠缺的是定义其他页面可以继承的“母版页”能力。开发人员通过使用用户控件&#xff08;它们可以容易地在页面之间复制&#xff09;创建页…

清华团队训了个AI,掌握了互联网流量密码…

随着NLP深入发展&#xff0c;AI写作风生水起。如果说自媒时代&#xff0c;UGC&#xff08;User Generated Content&#xff0c;用户生成内容&#xff09;是主流&#xff1b;智媒时代&#xff0c;AIGC是否会爆火&#xff1f;早听说过用AI写文章&#xff0c;以前小编我也试过用一…

程序员面试金典 - 面试题 08.10. 颜色填充(BFS/DFS)

1. 题目 颜色填充。编写函数&#xff0c;实现许多图片编辑软件都支持的“颜色填充”功能。 给定一个屏幕&#xff08;以二维数组表示&#xff0c;元素为颜色值&#xff09;、一个点和一个新的颜色值&#xff0c;将新颜色值填入这个点的周围区域&#xff0c;直到原来的颜色值全…

excel两列数据对比找不同_Excel“找不同”小妙招来啦,请查收

1、同表格两列数据找不同(1)对应位置找不同方法&#xff1a;选中待对比区域&#xff0c;按【Ctrl】组合键即可将不同之处标注出来。(2)位置不定找不同方法&#xff1a;依次点击“开始——条件格式——突出显示单元格显示规则——重复值”&#xff0c;然后设置对应突出显示颜色即…

谷歌PaLM杀疯了,已从语言模型进化成机器人大脑??

文 | 天于刀刀开篇小编想了解一下&#xff0c;有多少小伙伴和我一样在看完《复联》后对钢铁侠托尼的智能管家贾维斯非常眼馋&#xff0c;然后坚定了自己 all in 人工智能算法这条&#xff08;不归&#xff09;路的&#xff1f;理想中&#xff1a;你是个成熟的 AI 管家&#xff…

程序员面试金典 - 面试题 17.04. 消失的数字(数学/位运算)

1. 题目 数组 nums 包含从0到n的所有整数&#xff0c;但其中缺了一个。 请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗&#xff1f; 注意&#xff1a;本题相对书上原题稍作改动 示例 1&#xff1a; 输入&#xff1a;[3,0,1] 输出&#xff1a;2示例 2&#xff1…