c++ new delete 常踩的坑
WeTest 导读
c++ 是公司开发最常用的语言之一, 那New和Delete 这两个函数是所有开发者即爱又恨的函数。由new 和delete引发的bug , coredump , 让多少程序员加了多少班。
一、遇到的问题
C++ 中,你也许经常使用 new 和 delete 来动态申请和
● 释放内存,但你可曾想过以下问题呢?
● new 和 delete 是函数吗?
● new [] 和 delete [] 又是什么?什么时候用它们?
● 你知道 operator new 和 operator delete 吗?
为什么 new [] 出来的数组有时可以用 delete 释放有时又不行?
二、发现的代码
有时看到代码是这么写的:

这样有问题吗 ? 在服务器上长期运行,会引起内存泄漏吗?
写了个测试程序, 看看这些都是神马。



程序运行结果:

注意这里多出来的 4字节
三、总结
这个问题直接导致我们需要在 new [] 一个对象数组时,需要保存数组的维度,C++ 的做法是在分配数组空间时多分配了 4 个字节的大小,专门保存数组的大小,
在 delete [] 时就可以取出这个保存的数,就知道了需要调用析构函数多少次了。

四、c++对象内存分配与释放
有人提出两个问题:
1、那个4字节在 delete [] , 是怎么跳过的。
2、free 是怎么知道自己的长度。
以下写几个栗子 看一下:
delete 对象 :

部分汇编码如下:

delete复杂数据类型先调用析构函数再调用operator delete。
c++的内存分配
看一下 M$ 编译器是如何构造和释放内存的


小的总结
内存分配一般有两种方式:
1 非入侵式,内存分配器自行先申请内存(和栈配合使用),用作记录用户层的申请记录(地址,大小)。 用户释放空间时会查找该表,除了知道释放空间大小外还能判断该指针是合法。
2 入侵式,例如用户要申请1byte的内存,而内存分配器会分配5byte的空间(32位),前面4byte用于申请的大小。释放内存时会先向前偏移4个byte找到申请大小,再进行释放。
两种方法各有优缺点,第一种安全,但慢。第二种快但对程序员的指针控制能力要求更高,稍有不慎越界了会对空间信息做成破坏。
绝大多数的分配器会采用第一种方式实现,而操作系统级的分配器采用了虚拟等方式,可能要记录更多信息。
五、最后分析自定义数组类型
那么数组的分配和释放是 怎么自动的 增加 4 字节 和 减 4字节的呢?

实在不想看了 ,贴一点 关键的吧 , New 对象的部分汇编

上面的汇编码流程大致是:
1、调用operator new分配堆空间
2、调用构造代理函数构造堆对象,在调用构造代理函数时,通过压栈,像其传递了5个参数,分别是 a)第一个堆对象首地址 b)堆对象大小c)堆对象个数 d)构造函数地址 e)析构函数地址
3、传回第一个堆对象首地址,而不是申请到的堆空间首地址
析构的部分代码
看看析构函数是如何自动偏移4字节的。

以上的汇编似乎没有涉及 4字节的偏移 , 那看看 vector deleting destructor 这个函数干了啥

看到 operator delete[] (0341244h) 这个函数了 , 前面将 对象首地址 -4 ,然后释放内存, 现在知道为啥 析构偏移4字节了吧
关于腾讯WeTest (wetest.qq.com)
腾讯WeTest是腾讯游戏官方推出的一站式游戏测试平台,用十年腾讯游戏测试经验帮助广大开发者对游戏开发全生命周期进行质量保障。腾讯WeTest提供:适配兼容测试;云端真机调试;安全测试;耗电量测试;服务器性能测试;舆情分析等服务。
点击地址:http://wetest.qq.com/立即体验!
c++ new delete 常踩的坑的更多相关文章
- 从零开始学 Java - Spring 支持 CORS 请求踩的坑
谁没掉进过几个大坑 记得好久之前,总能时不时在某个地方看到一些标语,往往都是上面一个伟人的头像,然后不管是不是他说的话,下面总是有看起来很政治正确且没卵用的屁话,我活到目前为止,最令我笑的肚子痛得是下 ...
- webuploader插件,我踩得坑
我在目前的公司做的项目要么是原生写法去做项目,要么就是vue+webpack做项目,但是vue这部分只是用了模板template,vue其他的都没用. 有一个项目需要做上传图片的功能,老大扔给我一个插 ...
- 谈谈调用腾讯云【OCR-通用印刷体识别】Api踩的坑
一.写在前面 最近做项目需要用到识别图片中文字的功能,本来用的Tesseract这个写的,不过效果不是很理想. 随后上网搜了一下OCR接口,就准备使用腾讯云.百度的OCR接口试一下效果.不过这个腾讯云 ...
- Asp.Net Core中使用Swagger,你不得不踩的坑
很久不来写blog了,换了新工作后很累,很忙.每天常态化加班到21点,偶尔还会到凌晨,加班很累,但这段时间,也确实学到了不少知识,今天这篇文章和大家分享一下:Asp.Net Core中使用Swagge ...
- python绘图踩的坑
踩的坑 pyecharts安装地图包 pip install echarts-countries-pypkg 报错Unknown or unsupported command 'install' 这可 ...
- 使用CCNode作为容器容易踩的坑
Cocos2dx中CCNode经常作为一个父容器,里面装一些UI控件,最后组成一个复杂的自定义的UI控件,但是在使用别人的自定义控件和自己写自定义问题的时候会踩一些坑. 首先拿到一个自定义的UI控件一 ...
- java基础不牢固容易踩的坑
java基础不牢固容易踩的坑 经过一年java后端代码以及对jdk源码阅读之后的总结,对java中一些基础中的容易忽略的东西写下来,给偏爱技术热爱开源的Coder们分享一下,避免在写代码中误入雷区. ...
- Ubuntu中安装FTP 服务器自己踩得坑
12点多了,擦!做个码农真不容易呀! 系统:Ubuntu16.04 安装:FTP 步骤: 1.不管有没有一上来我先卸载: sudo apt-get purge vsftpd 2.再安装:sudo ap ...
- python——pyinstaller踩的坑 UnicodeDecodeError
程序本身运行没任何毛病,奈何用pyinstaller -w xx.py的时候提示——UnicodeDecodeError: 'ascii' codec can't decode byte 0xb3 i ...
随机推荐
- 用java读写ini配置文件
本文转载地址: http://www.blogjava.net/silvernapoleon/archive/2006/08/07/62222.html import java.io.Bu ...
- iOS自动打包并发布脚本
假如你的项目目录如下所示: |____AOP | |____AppDelegate.h | |____AppDelegate.m | |____Base.lproj | | |____LaunchSc ...
- python之路 序列化 pickle,json
运行代码,毫不留情地得到一个TypeError: Traceback (most recent call last): ... TypeError: <__main__.Student obje ...
- MySQL开放远程登录
在服务器上部署MYSQL每次观看MYSQL记录或者修改的时候都需要登录服务器,又烦又占资源.所以使用另一种方法:对外开放接口. 注:如果某些服务器开启防火墙屏蔽了某些接口就有可能导致远程用户无法登录M ...
- Android依赖管理与私服搭建
在Android开发中,一个项目需要依赖许多的库,我们自己写的,第三方的等等,这篇文件介绍的就是自己搭建私服,创建自己的仓库,进行对我们自己写的库依赖管理.本文是在 mac book pro 环境上搭 ...
- Ubuntu环境下 matplotlib 图例中文乱码
最近做了一个最小二乘法的代码编写并用 matplotlib 绘制了一张图,但是碰到了中文乱码问题.简单搜索之后,发现有人总结出了比较好的方案,亲测可行.推荐给大家. 本文前提条件是 已经 安装好 ma ...
- javascript的运行过程以及setTimeout的运行机制
关于javascript的运行机制大家都应该有所了解了吧,其实javascript是一个单线程的机制,但是因为队列的关系它的表现会让我们感觉是一个多线程的错觉.javascript在运行的时候是这样的 ...
- iOS gcd 串行,并行,同步,异步代码研究
参考文章: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #527eff } span.s1 { } http: ...
- 活动页怎么切图photoshop
一 切固定大小的单个图片 1.用pc打开图像 2.按ctrl+A(全选) 3.点击 选择 ->变换选区 ->拉参考线(把参考线放到最中央)->按回车 ->ctrl+d(取消全选 ...
- SQLServer数据库操作
--创建数据库create database 在线考试系统on(name=在线考试系统_DATA,filename='E:\DB\在线考试系统_DATA.mdf',size=5mb,maxsize=2 ...