C/C++高级程序员必经之路-何为堆(详解)?

        大家好,我是玉无涯,如你们所见,我又来发车了。这次发车的主要原因是为了填补以前的坑,两年前的时候我给大家讲了栈空间,两年过去了,我也是时候将堆区给大家讲清楚了。

看过我文章的都知道,我讲东西呢都是比较深入的,既然要讲堆,首先就要把C/C++的特性稍微说一下,作为一名合格的C程序员,如果你不知道堆,那么你是失败的。堆的重要性甚至超过了栈,如果你要入职C++开发,那么面试官会有90%的概率会问你内存问题,其实大概率包括了堆空间(因为堆和指针息息相关,指针的高级篇部分必须要有堆的基础)。那么废话不多说,我们赶紧发车。

C语言作为一门最接近底层的高级语言,它的自由度可谓非常的高,可以这么说,C语言的指针玩的很好,那么可以做到任何语言能做的事情,只是会非常复杂。倒不是说达不到那么好的效果,恰恰相反,在性能方面直接操作内存的特性可以秒杀任何一门高级语言。那么怎么操作内存,这个就很关键了。

我们都知道,C/C++都是以指针操作内存的,可是一般情况下,栈区是没有多少内存的,也就2MB左右(一般的笔记本或家用型电脑),而且栈区内存也不是自由调配的,他只能操作已经存在于栈区的变量,而栈区中变量的生命周期一般由函数决定,所以用起来并不方便。

所以,堆区的重要性就来了。在任何C/C++大型的软件开发中,你一定可以看到(如果你能看到)大量的指针,如果对堆区不了解的同学,看到大量的指针后就已经很懵了(哪来那么多指针,多此一举?),例如下面某个类的定义,如图所示(实战代码,还不点赞?):

如果里面的指针全部都指向栈区变量的内存,那么明显是不合理的。事实上,这上面的指针没有任何一个是存储栈区变量地址的。

问世间堆为何物?那么就由我玉无涯来告诉你们何为堆? 堆区简单来说就是可自由调度的内存(对于C/C++程序员来说),那么这块内存对比栈区有何优势?为什么这么重要呢?好的,这些问题一个个解答,首先优势如下:

1.堆区内存足够大,远远大于栈区,一般在2G左右(一般的笔记本或家用型电脑),甚至有些更大。

2.堆区内存不受作用域的影响(例如函数结束),由程序员自由分配与释放。

以上两点就是堆区最核心的两点,在生产环境下,尤其是后端服务器的生产环境是7*24小时不停机工作的,例如王者荣耀和英雄联盟,基本都是24小时服务器全天运转,除了大型更新之外。大量的软件架构中,都需要为消息和事件所附带的数据分配内存,所以堆区的内存使用会非常频繁,而且及其宝贵,所以申请后的内存一定要记得释放,否则会引起内存泄漏。

堆区内存C语言和C++都有自己的申请方式:

C语言常用:malloc(申请)   free(释放)    C语言的申请不止malloc,今天这里只讲这个。

C++:new(申请)    delete(释放)

malloc和free用法如下所示(下面模拟数据传输):

怎么样?是不是有点绕?其实我可以省略掉函数那一步,或许你们会觉得更清晰,但是这样意义不大,因为堆的真正用途就是和指针搞一起的。那么指针和堆的关联用法或者稍微复杂点的都是必须掌握的,更何况我写的这个模拟代码,代码量才多少呢?如果这样就打退堂鼓,哈哈,那么你可以及时止损转换赛道了。以上就是malloc和free的用法。

注意:malloc申请的内存是按照字节数进行申请的,所以函数内的参数其实是一个整数,这里我们用sizeof()计算出了类型的大小*需要的个数,就是我们真正需要分配的字节数。

还有一点,malloc分配的内存返回的是void*的地址,需要进行强制类型转化,这样才能被需要的类型所兼容,例如以上的例子。malloc函数原型是:void *malloc(uint32_t size);

free就很好理解了,只需要把你要释放的内存地址传递进去即可。

那么C++的new和delete怎么用呢?

其实会了malloc和free之后new和delete就很简单了,以上就是new和delete的用法。

注意:new分配的内存是按照类型进行分配的,是分配该类型的个数,而不是直接申请多少字节大小的内存,所以只需要在【】内写上个数就行。

还有一个重点,delete在释放内存的时候必须考虑这块内存是否被分配了多个该类型。如果在分配的时候分配了多个,那么在释放的时候一定要加上delete []进行释放,避免内存泄漏。

最后我来解答一下大家的疑问,有些工作两三年的程序员也不知道的东西。new和malloc的区别在哪?用哪个合适?其实以效率方面来看new会更快,因为new其实是运算符,它分配内存的效率会高于malloc,那么malloc呢?malloc和free都是系统调用,什么是系统调用?(这个就涉及Linux操作系统了,这里不解释)。关于安全方面,malloc或许会更适用,因为它是系统调用,哈哈哈。(不了解系统调用的Linux程序员连中级都算不上,因为根本没搞懂效率问题)。
最后请大家思考一个问题:new malloc free delete 可以混用吗?为什么可以呢?会出现什么问题呢?

以上就是这期博客的内容,关于数据内存图我就没做了,栈区那篇有,感兴趣可以去看看,至此程序员最重要的堆栈已经被搞定了。这个坑填完了,下次见不知道何时,这个大环境下,希望各位能学到点真东西吧,别被优化了。

我是程序员玉无涯,我们下次见......

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值