问题聚焦:
    我们都知道,new和delete要成对使用,但是有时候,事情往往不是按我们预期的那样发展。
    对于单一对象和对象数组,我们要分开考虑
    遇到typedef时,也需要搞清楚,是单一对象类型还是对象数组类型
 

来看一个例子:
std::string* stringArray = new std::string[100];
...
delete stringArray;
问题:stringArray所含的100个string对象中的99个可能并没有被适当地删除,因为它们的析构函数很可能没有被调用。

我们来了解一下,使用new时发生了什么,一共有两个动作:
  1. 内存被分配出来
  2. 针对此内存会有一个或更多个构造函数被调用
使用delete,也有两个动作:
  1. 针对此内存会有一个或更多个析构函数被调用
  2. 内存被释放
简单地说就是:
    即将被删除的那个指针,所指的是单一对象,还是对象数组。

内存分布:单一对象和对象数组的内存分布
    
正如上图所示,数组所用的内存往往还包括“数组大小”的记录,以便delete知道需要调用多少次析构函数。
当对着一个指针使用delete,唯一能够让它知道当前是删除单一对象还是对象数组的方法就是,由你来告诉它。
如下面这样:
std::string* stringPtr1 = new std::string;
std::string* stringPtr2 = new std::string[100];
...
delete stringPtr1;
delete[] stringPtr2;
如果对stringP1使用delete[] 这种形式,结果也不一定让人愉快,因为它读取的数组大小显然是错误的。
那我们应该怎么办呢?解决方案很简单:
如果你调用new时,使用new[] 的形式,那么对应调用delete时也使用[],
如果你调用delete时,没有使用new[] 的形式,那么对应调用delete时也不应该使用[] 形式。
当你设计的class含有一个指针指向动态分配内存,并提供多个构造函数时,上述的规则尤为重要。
这时,你需要小心地在所有构造函数中使用相同形式的new将指针成员初始化,同时,相应的析构函数也要使用相同的形式。

当使用typedef时,要变得尤为敏感,因为你必须要明确地知道,这时的new是一个什么样的形式:
typedef std::string AddressLines[4];       // 每个人的地址有4行,每行是一个string

// 这时候AddresLines是一个数组,所以new时,应该是[]形式
std:string* pal = new AddresLines; // 相当于:new string[4];
//那么,必须匹配数组形式的delete
delete pal; // error,行为未定义
delete[] pal; // pass
所以,最好尽量不要对数组形式使用typedef动作。

小结:
  • 如果在new表达式中使用[],必须在相应的delete表达式中也使用[]
  • 如果在new表达式中不使用[],一定不要再相应的delete表达式中使用[]
  • 尽量不要对对象数组使用typedef动作
参考资料:
《Effective C++ 3rd》

最新文章

  1. MapReduce剖析笔记之四:TaskTracker通过心跳机制获取任务的流程
  2. 使用ikmv将jar转换为dll,在.NET中直接调用
  3. Intent之前的对象传递与fragment传递数据
  4. Android消息的提示,Toast吐司方式
  5. Windows Azure Virtual Machine (30) 修改Azure VM 的Subnet
  6. 使用 google gson 转换Timestamp或Date类型为JSON字符串.
  7. 队列的C++实现(数组)——创建-进队-出队-返回队首元素-清空队列栈-处理队列
  8. uva 10994
  9. 关于css3 中filter的各种特效
  10. CMAKE 学习
  11. HDU 5501 背包问题
  12. 基于Sql Server 2008的分布式数据库的实践(三)
  13. C语言解析17monipdb.dat(http://www.ipip.net/)免费数据库
  14. Comparing Spring AOP and AspectJ
  15. RockerMQ实战之快速入门
  16. 泡泡一分钟:Towards real-time unsupervised monocular depth estimation on CPU
  17. NGUI制作字体的三种方法
  18. yii2之创建管理员
  19. ActiveMQ消息持久化存储策略
  20. 【手把手教你全文检索】Apache Lucene初探 (zhuan)

热门文章

  1. Android - 采用ApiDemos得知Android开展
  2. Nyoj 布线问题(并查集&&图论)
  3. Oracle 树操作
  4. C#记录日志、获取枚举值 等通用函数列表
  5. 由于问题引起信号ORA-27154无法启动数据库
  6. POJ 2109 :Power of Cryptography
  7. Hibeernate中的两种分页方式
  8. Delta3D 2.8版本号 预习
  9. linux网络编程学习笔记之四 -----多-threaded服务器
  10. java设计模式之四建造者模式(Builder)