转载自https://blog.csdn.net/cbNotes/article/details/38900799

1.我们通常从教科书上看到这样的说明:
delete 释放new分配的单个对象指针指向的内存
delete[] 释放new分配的对象数组指针指向的内存
那么,按照教科书的理解,我们看下下面的代码:

int *a = new int[];
delete a; //方式1
delete [] a; //方式2

肯定会有很多人说方式1肯定存在内存泄漏,是这样吗?

(1). 针对简单类型 使用new分配后的不管是数组还是非数组形式内存空间用两种方式均可 如:

int *a = new int[];
delete a;
delete [] a;

此种情况中的释放效果相同,原因在于:分配简单类型内存时,内存大小已经确定,系统可以记忆并且进行管理,在析构时,系统并不会调用析构函数,
   它直接通过指针可以获取实际分配的内存空间,哪怕是一个数组内存空间(在分配过程中 系统会记录分配内存的大小等信息,此信息保存在结构体_CrtMemBlockHeader中,

(2). 针对类Class,两种方式体现出具体差异
   当你通过下列方式分配一个类对象数组:

class A
{
private:
char *m_cBuffer;
int m_nLen;
public:
A()
{
m_cBuffer = new char[m_nLen];
}
~A()
{
delete [] m_cBuffer;
}
};
A *a = new A[];
delete a;
/*仅释放了a指针指向的全部内存空间但是只调用了a[0]对象的析构函数
剩下的从a[1]到a[9]这9个用户自行分配的m_cBuffer对应内存空间将不能释放
从而造成内存泄漏*/
delete [] a;
/*调用使用类对象的析构函数释放用户自己分配内存空间并且
释放了a指针指向的全部内存空间
*/

所以总结下就是,如果ptr代表一个用new申请的内存返回的内存空间地址,即所谓的指针,那么:
   delete   ptr   代表用来释放内存,且只用来释放ptr指向的内存。
   delete[]   rg   用来释放rg指向的内存,!!还逐一调用数组中每个对象的destructor!!
   对于像int/char/long/int*/struct等等简单数据类型,由于对象没有destructor,所以用delete 和delete [] 是一样的!但是如果是C++对象数组就不同了!

关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。
对于 (1),上面提供的程序已经证明了 delete[] 和 delete 是等同的。但是对于 (2),情况就发生了变化。
我们来看下面的例子,通过例子的学习了解C++中的delete和delete[]的使用方法

#include <iostream>
using namespace std;
class Babe
{
public:
Babe()
{
cout << "Create a Babe to talk with me" << endl;
}
~Babe()
{
cout << "Babe don't go away,listen to me" << endl;
}
};
int main()
{
Babe* pbabe = new Babe[];
delete pbabe;
pbabe = new Babe[];
delete []pbabe;
return ;
}

结果是:

Create a Babe to talk with me
Create a Babe to talk with me
Create a Babe to talk with me
Babe don't go away,listen to me
Create a Babe to talk with me
Create a Babe to talk with me
Create a Babe to talk with me
Babe don't go away,listen to me
Babe don't go away,listen to me
Babe don't go away,listen to me

大家都看到了,只使用delete的时候只出现一个 Babe don't go away,listen to me,而使用delete[]的时候出现3个 Babe don't go away,listen to me。不过不管使用delete还是delete[]那三个对象的在内存中都被删除,既存储位置都标记为可写,但是使用delete的时候只调用了pbabe[0]的析构函数,而使用了delete[]则调用了3个Babe对象的析构函数。

你一定会问,反正不管怎样都是把存储空间释放了,有什么区别。答:关键在于调用析构函数上。此程序的类没有使用操作系统的系统资源(比如:Socket、File、Thread等),所以不会造成明显恶果。如果你的类使用了操作系统资源,单纯把类的对象从内存中删除是不妥当的,因为没有调用对象的析构函数会导致系统资源不被释放,如果是Socket则会造成Socket资源不被释放,最明显的就是端口号不被释放,系统最大的端口号是65535(216 _ 1,因为还有0),如果端口号被占用了,你就不能上网了,呵呵。如果File资源不被释放,你就永远不能修改这个文件,甚至不能读这个文件(除非注销或重器系统)。如果线程不被释放,这它总在后台运行,浪费内存和CPU资源。这些资源的释放必须依靠这些类的析构函数。所以,在用这些类生成对象数组的时候,用delete[]来释放它们才是王道。而用delete来释放也许不会出问题,也许后果很严重,具体要看类的代码了.

C++ delete 和 delete []的区别的更多相关文章

  1. 【转】 C++中delete和delete[]的区别

    一直对C++中的delete和delete[]的区别不甚了解,今天遇到了,上网查了一下,得出了结论.做个备份,以免丢失. C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete ...

  2. oracle中drop、delete和truncate的区别

    oracle中drop.delete和truncate的区别 oracle中可以使用drop.delete和truncate三个命令来删除数据库中的表,网上有许多文章和教程专门讲解了它们之间的异同,我 ...

  3. Delete和Truncate的区别

    原文:Delete和Truncate的区别 一般对于没有用的数据,都会经行删除,而删除通常使用的是DELETE和TRUNCATE命令.对于有条件地删除,基本上就会使用DELETE,当然还是没有绝对,用 ...

  4. C++ 中 delete 和 delete[] 的区别

    一直对 C++ 中 delete 和 delete[] 的区别不甚了解,今天遇到了,上网查了一下,得出了结论.做个备份,以免丢失. C++ 告诉我们在回收用 new 分配的单个对象的内存空间时用 de ...

  5. delete与delete[]的区别

    一直对C++中的delete和delete[]的区别不甚了解,今天遇到了,上网查了一下,得出了结论.做个备份,以免丢失. C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete ...

  6. delete和delete[]的区别(转载)

    一直对C++中的delete和delete[]的区别不甚了解,今天遇到了,上网查了一下,得出了结论.做个备份,以免丢失. C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete ...

  7. new和malloc区别,delete和delete []区别

    面试被问到上述问题,所以特地总结一下: 一.new和malloc的区别. 1.new可以返回指定类型的指针,并且自动分配内存大小:malloc需要计算手动计算分配空间的大小,并且返回值需要强转为实际类 ...

  8. delete 和 delete [] 的真正区别

    c++中对new申请的内存的释放方式有delete和delete[两种方式,到底这两者有什么区别呢? 1.我们通常从教科书上看到这样的说明: delete 释放new分配的单个对象指针指向的内存 de ...

  9. delete和delete[] 区别

    // DeleteAndDelete[].cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h> ...

  10. 数据库中drop、delete与truncate的区别

    数据库中drop.delete与truncate的区别 drop直接删掉表: truncate删除表中数据,再插入时自增长id又从1开始 :delete删除表中数据,可以加where字句. (1) D ...

随机推荐

  1. R学习

    R内容: R-1 基础 R-2 基础绘图 R-3 t分布--t置信区间--t检验 R-4 方差分析 R-5 相关分析-卡方分析 R-6 线性回归模型分析流程 R实战第7章 线性回归 逻辑回归 主成分分 ...

  2. Ubuntu18.04 卸载mysql5.7

    查看MySQL的依赖项:dpkg --list|grep mysql 要删除上面的这些. 开始卸载: sudo apt-get autoremove --purge mysql-server sudo ...

  3. 从壹开始[做贡献]之二 || 推荐VSCode多语言开发,支持一键JAVA

    缘起 哈喽大家周一好!好久不见鸭,最近在看一本书,很好,<人类简史>,适合夏日星空,仰观宇宙之大

  4. Python中的模块引用机制

    一.模块引用 Def: 在Python 程序中使用另一个文件定义的类(方法).函数.数据等 被引用模块位置.通常 Python2 : "/Library/Python/2.7/site-pa ...

  5. [译]Vulkan教程(11)Image Views

    Image views To use any VkImage, including those in the swap chain, in the render pipeline we have to ...

  6. EF中存储过程的使用

    存储过程即用来完成一个特定功能的一段代码.它的优缺点 优点 存储过程可封装,并隐藏复杂的商业逻辑. 存储过程可以回传值,并可以接受参数. 存储过程无法使用 SELECT 指令来运行,因为它是子程序,与 ...

  7. window.innerHeight和document.documentElement.clientHeight区别

    今天有人问我这个问题,做了个小例子来记录一下子. 首先这两个都是获取可视区域的高度,那他们有什么区别呢 1.window.innerHeight属于BOM(浏览器对象模型),而document.doc ...

  8. 平时代码中用不到设计模式?Are you kidding me?

    引子 平时我是个反应非常慢的人.有多慢呢?大概是两年前有次团队内部开会时,我听到同学说平时代码中用不到设计模式,我当时没有回答.两年后我终于反应过来了:“Are you kidding me?我每天都 ...

  9. JS(TS)中数组常见的方法(未完待续)

    push():向数组末尾添加一个或多个元素 unshift(): 向数组的开头添加一个或多个元素 pop(): 删除数组最后一个元素 shift(): 删除数组第一个元素 sort(): 给数组排序  ...

  10. Dojo.declare使用方法详解

    ArcGIS API for JavaScript是基于dojo开发的一套API,在实际生产中,我们需要再根据自己的需求实现自定义的功能,最后抽象成接口给前端调用. 我们使用dojo的declare来 ...