请牢记:

如果在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时要使用相同的形式的更多相关文章

  1. Effective C++(16) 成对使用new和delete时要采取相同的形式

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

  2. 读书笔记 effective c++ Item 16 成对使用new和delete时要用相同的形式

    1. 一个错误释放内存的例子 下面的场景会有什么错? std::]; ... delete stringArray 一切看上去都是有序的.new匹配了一个delete.但有一些地方确实是错了.程序的行 ...

  3. 条款16:成对使用new和delete时,采取相同的形式

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

  4. 条款16:成对使用 new和delete时要采取相同的形式

    std::string* stringPtr1=new std::string; srd::string* stringPtr2=new std::string[100];   对应地 delete也 ...

  5. Effective C++ -----条款16:成对使用new和delete时要采取相同形式

    如果你在new表达式中使用[],必须在相应的delete表达式中也使用[].如果你在new表达式中不使用[],一定不要在相应的delete表达式中使用[].

  6. 条款16:成对使用new和delete时要采取相同形式

    NOTE: 1.如果你在new表达式中使用[],必须在相应的delete表达式中也使用[].如果你在new表达式中不使用[],一定不要在相应的delete表达式中使用[].

  7. EC笔记:第三部分:16成对使用new和delete

    我们都知道,申请的资源,使用完毕后要释放.但是这个释放动作,一定要注意. 举个例子,很多人动态分配的资源,在使用之后,往往直接调用了delete,而不管申请资源的时候用的是new还是new[]. 如下 ...

  8. 【16】成对使用new和delete时要采取相同形式

    简而言之,new时不带[],delete时也不带[]:new时带[],delete时也要带[].如果不匹配,要么造成多销毁对象,导致未定义行为:要么导致少销毁对象,导致内存泄漏.

  9. 条款八: 写operator new和operator delete时要遵循常规

    自己重写operator new时(条款10解释了为什么有时要重写它),很重要的一点是函数提供的行为要和系统缺省的operator new一致.实际做起来也就是:要有正确的返回值:可用内存不够时要调用 ...

随机推荐

  1. Android Studio官方文档: 如何在你的设备上运行你的程序

    在实体设备上运行您的应用 设置您的设备,如下所示: 使用一根 USB 电缆将您的设备连接到您的开发机器. 如果您是在 Windows 上开发,可能需要为您的设备安装相应的 USB 驱动程序.如需帮助安 ...

  2. Troubleshooting routing topology based on a reference topology

    In one embodiment, a computing device (e.g., border router or network management server) transmits a ...

  3. .net程序运行流程

    程序员用.net开发的程序要在计算机上运行,首先程序经过编译后,会生成机器指令,一般以一个文件的形式保存,这个文件在外存储器上(存储器分外存与内存.外存:硬盘,U盘等:) 然后cpu会把硬盘上的文件读 ...

  4. Method and Apparatus for Providing Highly-Scalable Network Storage for Well-Gridded Objects

    An apparatus comprising a plurality of storage nodes comprising a plurality of corresponding storage ...

  5. ssh探头安全

    1.  ssh 合约                 SSH 为建立在应用层和传输层基础上的安全协议. SSH 是眼下较可靠,专为远程登录会话和其它网络服务提供安全性的协议.利用 SSH 协议能够有效 ...

  6. 转:spring MVC HTTP406 Not Acceptable

    springMVC框架下,ajax请求,在用json对象返回的时候,可以用如下的形式: response.setContentType("text/html;charset=UTF-8&qu ...

  7. 2-1 Consul简介

    Consul英文意思是大使馆. Consul主要干3件事情: 1.提供服务到ip地址的注册. 2.提供服务到ip地址列表的查询. 3.对提供服务方的健康检查. Consul官网 :https://ww ...

  8. 对XAML进行编辑的辅助类(XamlHelper)

    原文:对XAML进行编辑的辅助类(XamlHelper) // XamlHelper.cs// --------------------------------------------// 对XAML ...

  9. 乞讨 间隔[a,b]在见面p^k*q*^m(k&gt;m)中数号码

    标题叙述性说明: 1<=a,b<=10^18,p,q他们是素数  2<=p,q<=10^9; 求在[a,b]内能够表示为  x*p^k*q^m  k > m   的数的个 ...

  10. C#: Get current keyboard layout\input language

    原文 https://yal.cc/csharp-get-current-keyboard-layout/ On some occasions, you may want to get a " ...