在平时资料中,我们常看到:new和delete,new[]和delete[]一定要配对使用!有时候不配对使用也不会出现问题。也许你也是只知其然,不知其所以然,然而我也有点懵了。

在平时资料中,我们常看到:new和delete,new[]和delete[]一定要配对使用!

也有人说:有时候不配对使用也不会出现问题。也许你也是只知其然,不知其所以然,然而我也有点懵了_(¦3」∠)_

那就研究下这个问题:

首先,看下这段配对使用代码:

#include
#include
using namespace std;
class inner {  public:  inner() { cout << "Constructing" << endl; }  ~inner() { cout << "Destructing" << endl; }
};
int main(int argc, char *argv[]) {  inner *p = new inner();  inner *pa = new inner[2];  delete p;  delete []pa;  return 0;
}
程序输出:
Constructing
Constructing
Constructing
Destructing
Destructing
Destructing

因为new[]会创建一个数组,一个对象数组需要一定的空间大小,假设一个对象需要N字节大小,K个对象的数组就需要K*N个空间来构造对象数组,但是在delete[]时候,如何知道数组的长度呢?

所以new[]会在K*N个空间的基础上,头部多申请4个字节,用于存储数组长度,这样delete[]时候才知道对象数组的大小,才会相应调用K次析构函数,并且释放K*N+4大小的内存。

这是我们平时编程中经常配对使用的情况,如果不配对使用呢?

new[]与delete结对使用

#include
#include
using namespace std;
class inner {  public:  inner() { cout << "Constructing" << endl; }  ~inner() { cout << "Destructing" << endl; }
};
int main(int argc, char *argv[]) {  inner *p = new inner[2];  delete p;  return 0;
}
程序输出:
Constructing
Constructing
Destructing
munmap_chunk(): invalid pointer
Aborted (core dumped)

这里发现:程序挂掉了。

并且,只调用了一次析构函数,为什么呢?

因为我们使用了delete,delete不同于delete[],它认为这只是一个对象占用的空间,不是对象数组,不会访问前4个字节获取长度,所以只调用了一次析构函数。而且,最后释放内存的时候只释放了起始地址为A的内存。然而这不是这一整块内存的起始地址,整块内存的起始地址应该是A-4,释放内存如果不从内存起始地址操作就会出现断错误,所以导致程序挂掉。

关于内存知识可以看我以前的文章:

10张图22段代码,万字长文带你搞懂虚拟内存模型和malloc内部原理

new和delete[]结对使用

#include
#include
using namespace std;
class inner {  public:  inner() { cout << "Constructing" << endl; }  ~inner() { cout << "Destructing" << endl; }
};
int main(int argc, char *argv[]) {  inner *p = new inner();  delete []p;  return 0;
}
程序输出:
Constructing
Destructing
Destructing
Destructing
Destructing
Destructing
Destructing
...
Destructing
free(): invalid pointer
Aborted (core dumped)

这里调用了不定次数的析构函数,并且挂掉,是因为在new时候没有多申请4个字节存储长度,而delete[]时候还会向前找4个字节获取长度,这4个字节是未定义的,所以调用了不固定次数的析构函数,释放内存的时候也释放了起始地址为A-4的内存,而正常的起始地址应该是A,所以程序挂掉。

什么时候可以不配对使用?

我们再来看一段代码:

#include
#include
using namespace std;
int main() {  int *pint = new int(5);  delete[] pint;  int *pinta = new int[4];  delete pinta;  cout << "success" << endl;  return 0;
}
程序输出:
success

这段代码即使不配对使用也会正常运行,这是为什么呢,因为int是内置类型,new[]和delete[]在配合int使用时知道int是内置类型,不需要析构函数,所以也就不需要多4个字节来存放数组长度,只需要直接操作内存即可。

编程中new[]和delete[]应该如何使用?相关推荐

  1. fileoutputstream路径 android,Android编程中FileOutputStream与openFileOutput()的区别分析

    本文实例分析了Android编程中FileOutputStream与openFileOutput()的区别.分享给大家供大家参考,具体如下: openFileOutput() 首先给大家介绍使用文件如 ...

  2. C语言编程中的“堆”和“栈”七大不同之处

    对于编程初学者来说会接触到一些难以理解的名称,比如堆(heap).栈(stack).堆栈(stack)等.初学开发过程中往往让人混淆不清.今天我们来谈谈堆和栈的具体区别,来帮助初学者理清思路. 堆和栈 ...

  3. c语言中错误executing,C语言编程中常见问题解读.doc

    C语言编程中常见问题解读 为什么vc6打开的文件却不能编译1 为什么一个vc6工程中有两个main函数不能编译成功?我想写两个程序怎么办?2 为什么v6不能编译程序,生成信息说compile和link ...

  4. php中new运算符的作用,C++_C++编程中new运算符的使用学习教程,new运算符用作从自由存储为 typ - phpStudy...

    C++编程中new运算符的使用学习教程 new运算符用作从自由存储为 type-name 的对象或对象数组分配内存,并将已适当分类的非零指针返回到对象. [::] new [placement] ne ...

  5. python编程中常用的12种基础知识总结

    python编程中常用的12种基础知识总结:正则表达式替换,遍历目录方法,列表按列排序.去重,字典排序,字典.列表.字符串互转,时间对象操作,命令行参数解析(getopt),print 格式化输出,进 ...

  6. c语言获取系统剩余内存_C语言编程中的“堆”和“栈”七大不同之处

    更多精彩,请点击上方蓝字关注我们! 对于编程初学者来说会接触到一些难以理解的名称,比如堆(heap).栈(stack).堆栈(stack)等.初学开发过程中往往让人混淆不清.今天我们来谈谈堆和栈的具体 ...

  7. python编程的基本方法有哪些_Python编程中常用的基础知识有哪些?

    今天小编要跟大家分享的文章是关于Python编程中常用的基础知识有哪些?正在从事Python相关工作的小伙伴们,来和小编一起看一看本篇文章,希望本篇文章能够对大家有所帮助. 1.正则表达式替换 目标: ...

  8. 套接字编程---2(TCP套接字编程的流程,TCP套接字编程中的接口函数,TCP套接字的实现,TCP套接字出现的问题,TCP套接字多进程版本,TCP套接字多线程版本)

    TCP模型创建流程图 TCP套接字编程中的接口 socket 函数 #include <sys/types.h> /* See NOTES */ #include <sys/sock ...

  9. c mysql 工具类_Jave工具——servlet+jsp编程中mysql数据库连接及操作通用工具类

    该工具类是在JavaWeb中连接mysql所用到的通用工具类 该类用于Java+Servlet的编程中,方便数据库的操作,连接,获取其列表值.下面是这个数据库操作类的通用方法,基本上能够用于类里面只含 ...

最新文章

  1. vue2.0transition过渡的使用介绍
  2. 『Tarjan算法 无向图的双联通分量』
  3. IP协议号(TCP协议号/UDP协议号)
  4. 超大规模数据中心容量在四年内翻了一番,中国占比15%
  5. 2017.4.5下午
  6. 玩英雄联盟手游,谁才是新手最喜欢的英雄?无极剑圣还是吗?
  7. SAP Spartacus B2B unit list页面抬头的计数逻辑的实现原理
  8. dsu on tree入门
  9. mssql 动态行转列。
  10. 中文NER碎碎念—聊聊词汇增强与实体嵌套
  11. 虚拟机vBox xp系统无法联网
  12. Python读取视频方法
  13. 圆和长方形周长相等谁的面积大_周长相等,正方形、长方形、圆形谁的面积最大?...
  14. 清华领军计划计算机试题,清华大学2017自主招生真题
  15. awk NR详解!awk 的内置变量 NF、NR、FNR、FS、OFS、RS、ORS
  16. #自动化测试框架的4种有效分类与使用选择
  17. Daily Scrum Meeting 11.13
  18. 《Windows 8 权威指南》——2.8 Metro版IE10,探测Windows 8 Metro应用的撒手锏
  19. oracle substr clob,sql – 在CLOB上的SUBSTR的性能
  20. 鸿蒙系统沙箱,鸿蒙计划加速!亦来云成操作系统的救命稻草?

热门文章

  1. 客户花钱雇黑客,竟是为Zoom找bug:风口浪尖的视频会议No.1,安全问题如此魔幻...
  2. 一篇长文带你在python里玩转Json数据
  3. 精心总结 Python『八宗罪』,邀你来吐槽
  4. 【每日一算法】二叉树的层次遍历 II
  5. linux定时任务简记
  6. Python异步通信模块asynchat
  7. Linux 之Cut命令详解
  8. Python自动化办公系列之Python操作PDF
  9. 从入门到放弃心得 | 我为什么弃用GAN?
  10. Java如何执行操作系统的CMD命令行