条款16:成对使用new和delete时要使用相同的形式
请牢记:
如果在new表达式中使用[],必须在相应的delete表达式中也使用[]。 new[] 对应 delete[]
如歌在new表达式中不适用[],一定不要在相应的delete表达式中使用[]。 new 对应 delete
当使用new时(即通过new动态生成一个对象),有两件事发生:第一,内存被分配出来(通过名为operator new 的函数);第二,针对此内存会有一个(或更多)构造函数被调用。
当使用delete时,也有两件事发生:针对此内存会有一个(或更多)析构函数被调用,然后内存才被释放(通过名为operator delete 的函数)。delete的最大问题在于:即将被删除的内存之内有究竟存有多少对象?(即将被删除的那个指针,所指的是单一对象或对象数组?)此问题的答案决定了又多少个析构函数必须被调用起来。
单一对象的内存布局不同于对象数组的内存布局:数组所用的内存包括“数组大小”记录,以便delete制定需要调用多少次析构函数。单一对象的内存则没有这笔记录。
delete[]认定指针指向一个数组,多次调用析构函数。因此切记 new和delete时要采取相同形式。
std::string* strPtr1 = new std::string;
std::string* strPtr2 = new std::string[100];
...
delete strPtr1; //删除一个对象
delete [] strPtr2; //删除一个由对象组成的数组
如果对strPtr1使用delete[]形式:delete会读取若干内存并解释为“数组大小”,然后多次调用析构函数。
如果对strPtr2没使用delete[]形式:可能导致99个析构函数没被调用,对象不太可能被适当删除。
也就是说,以上的两种情况都可能会导致不确定的行为哟~
对于typedef动作,当以new创建该种typedef类型对象时,应该说清楚应该以哪一种delete形式删除。
考虑下面这个例子:
typedef std::string AddressLines[4];//每个人的地址有4行 每行是一个string //AddressLines是个数组,如果这样使用new:
std::string* pal = new AddressLines;//返回一个string* 跟new string[4]一样
那就必须匹配“数组形式”的delete[]:
delete pal; //行为未有定义!!!
delete [] pal; //OK
为避免诸如此类的错误,最好尽量不要对数组形式做typedef动作。取而代之可以使用vector<string>等templates。
条款16:成对使用new和delete时要使用相同的形式的更多相关文章
- Effective C++(16) 成对使用new和delete时要采取相同的形式
问题聚焦: 我们都知道,new和delete要成对使用,但是有时候,事情往往不是按我们预期的那样发展. 对于单一对象和对象数组,我们要分开考虑 遇到typedef时,也需要 ...
- 读书笔记 effective c++ Item 16 成对使用new和delete时要用相同的形式
1. 一个错误释放内存的例子 下面的场景会有什么错? std::]; ... delete stringArray 一切看上去都是有序的.new匹配了一个delete.但有一些地方确实是错了.程序的行 ...
- 条款16:成对使用new和delete时,采取相同的形式
问题聚焦: 我们都知道,new和delete要成对使用,但是有时候,事情往往不是按我们预期的那样发展. 对于单一对象和对象数组,我们要分开考虑. 遇到typedef时,也需要搞 ...
- 条款16:成对使用 new和delete时要采取相同的形式
std::string* stringPtr1=new std::string; srd::string* stringPtr2=new std::string[100]; 对应地 delete也 ...
- Effective C++ -----条款16:成对使用new和delete时要采取相同形式
如果你在new表达式中使用[],必须在相应的delete表达式中也使用[].如果你在new表达式中不使用[],一定不要在相应的delete表达式中使用[].
- 条款16:成对使用new和delete时要采取相同形式
NOTE: 1.如果你在new表达式中使用[],必须在相应的delete表达式中也使用[].如果你在new表达式中不使用[],一定不要在相应的delete表达式中使用[].
- EC笔记:第三部分:16成对使用new和delete
我们都知道,申请的资源,使用完毕后要释放.但是这个释放动作,一定要注意. 举个例子,很多人动态分配的资源,在使用之后,往往直接调用了delete,而不管申请资源的时候用的是new还是new[]. 如下 ...
- 【16】成对使用new和delete时要采取相同形式
简而言之,new时不带[],delete时也不带[]:new时带[],delete时也要带[].如果不匹配,要么造成多销毁对象,导致未定义行为:要么导致少销毁对象,导致内存泄漏.
- 条款八: 写operator new和operator delete时要遵循常规
自己重写operator new时(条款10解释了为什么有时要重写它),很重要的一点是函数提供的行为要和系统缺省的operator new一致.实际做起来也就是:要有正确的返回值:可用内存不够时要调用 ...
随机推荐
- ik_max_word ik_smart
打开 ~/es_root/config/elasticsearch.yml 文件,加入以下配置: index: analysis: analyzer: ik_syno: type: custom to ...
- php自动加载类文件探讨,spl_autoload_register自动加载原理
spl_autoload_register函数是实现自动加载未定义类功能的的重要方法,所谓的自动加载意思就是 我们的new 一个类的时候必须先include或者require的类文件,如果没有incl ...
- visio(2013)绘图工具的使用
1. 链接线 ⇒ 直线 visio2010中如何使画出来的连接线为直线 [设计面板] ⇒ 在最右端将[链接线]设置为直线: 2. 连接线交叉而不产生交叉桥(弯曲) visio2013画图时两条直线交叉 ...
- CUDA+OpenGL混合编程
CUDA+OpenGL混合编程示例: #include <stdio.h> #include <stdlib.h> #include "GL\glew.h" ...
- UVA 548(二进制重建和遍历)
J - Tree Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Status Ap ...
- cocos2d-x 源代码分析 总文件夹
这篇博客用来整理与cocos2d-x相关的工作,仅仅要有新的分析.扩展或者改动,都会更改此文章. 祝大家愉快~ 1.源代码分析 1.CCScrollView源代码分析 http://blog.csdn ...
- c#调用ffmpeg嵌入srt/ass字幕提示Cannot load default config file...
c#调用ffmpeg嵌入srt/ass字幕提示 Fontconfig error: Cannot load default config file[Parsed_subtitles_0 @ 00000 ...
- OpenGL(一)绘制圆、五角星、正弦曲线
OpenGL入门之"顶点":OpenGL规定,一个多边形必须是一个"凸多边形",即连接多边形上任意两点,其连线都在多边形内部.多边形可以由其边上的端点(这里可称 ...
- Linux性能测试 iostat命令
Linux系统出现了性能问题,一般我们可以通过top.iostat.free.vmstat等命令 来查看初步定位问题.其中iostat可以给我们提供丰富的IO状态数据.iostat 由 Red Hat ...
- Win7 64位系统,使用(IME)模式VS2010 编写 和 安装 输入法 教程(1)
原文:Win7 64位系统,使用(IME)模式VS2010 编写 和 安装 输入法 教程(1) 首先感谢:http://blog.csdn.net/shuilan0066/article/detail ...