文档章节

C++ delete失败

guoliang
 guoliang
发布于 2015/06/13 10:29
字数 668
阅读 113
收藏 0
点赞 0
评论 0

1. 指针通过 new 或 new[] ,向系统“申请”得到一段内存空间,这段内存空间必须在不需要将它释放了。

int *  p  =   new   int [ 100 ]; 
int  girl[ 100 ];  
p  =  girl;  
delete [] p;
   灾难在 delete [] p  时发生。 我们原意是要释放p最初通过new int[100] 而得到的内存空间,但事实上,p那时已经指向girl[100] 了。结果,第一、最初的空间并没有被释放。第二、girl[100]  本由系统自行释放,现在我们却要强行释放它。
2. 一个指针被删除时,应指向最初的地址

当一个指针通过 +,- 等操作而改变了指向;那么在释放之前,应确保其回到原来的指向。如下所示:在 delete [] p 时,p指向的是第二个元素,结果该释放将产生错位:第一个元素没有被释放,而在最后多删除了一个元素

int   * p  =   new   int [ 3 ];
* p  =   1 ;
cout  <<   * p  <<  endl;
p ++ ;  // p的指向改变了,指向了下一元素 
* p  =   2 ;
cout  <<   * p  <<  endl;
delete [] p;  // 错误的释放
p -- ;
delete [] p;
但当我们的指针指向变化很多次时,在释放前要保证一步不错地一一退回,会比较困难。所以另一方法是在最初时“备份”一份。在释放时,直接释放该指针即可。
int *  p  =   new   int [ 3 ];
int *  pbak  =   * p;  // 备份
 // 移动 p 
……
delete [] pbak;  // 释放
由于pbak正是指向p最初分配后的地址,我们删除pbak,就是删除p最初的指向。此时我们不能再删除一次p。这也就引出new / delete  new[] / delete[] 在本章的最后一个问题。

3. 已释放的空间,不可重复释放
第一种最直接:
int *  p  =   new   int ( 71 );
cout  <<   * p  <<  endl; 
delete p;  // OK! 
delete p;  // ERROR! 重复删除p
第二种为重复删除同一指向的多个指针
int *  p1  =   new   int ( 71 );
int *  p2  =  p1;  // p2和p1 现在指向同一内存地址
cout  <<   * p1  <<  endl;
cout  <<   * p2  <<  endl;
delete p1;  // OK 
delete p2;  // ERROR! p2所指的内存,已通过delete p1而被释放,不可再delete一次
同样的问题,如果你先删除了p2,则同样不可再删除p1
delete p2;  // OK 
delete p1;  // ERROR
第三种为删除指向某一普通变量的指针
int  a  =   100 ;
int *  p  =   & a;
delete p;  // ERROR

不是通过new 得到新的内存空间,而是直接指向固定变量a。所以删除p等同要强行剥夺a的固有空间,会导致出错。

4.当出现堆溢出的时候

char* p = new char[5];
char *str = "12345";//实际长度为6
strcpy(p,str);
delete[] p; //ERROR

本文转载自:http://www.cnblogs.com/laipDIDI/articles/2173532.html

共有 人打赏支持
guoliang
粉丝 26
博文 131
码字总数 27457
作品 0
杭州
程序员
浅谈MFC内存泄露检测及内存越界访问保护机制

本文所有代码均在VC2008下编译、调试。如果您使用的编译器不同,结果可能会有差别,但本文讲述的原理对于大部分编译器应该是相似的。对于本文的标题,实在不知道用什么表示更恰当,因为本文不...

songchang
2012/09/28
0
0
C++中的do{}while()

在C++中,有三种类型的循环语句:for, while, 和do...while, 但是在一般应用中作循环时, 我们可能用for和while要多一些,do...while相对不受重视。 但是,最近在读我们项目的代码时,却发现...

卢西安
2012/11/27
0
0
转载:do...while(0)的妙用

MTK中有很多有关do...while(0)的应用,刚开始可能有很多人不太明白为什么使用do...while(0),似乎不加do...while(0),该部分的代码也会只执行一次,其实do...while(0)是出于优化代码考虑的.do.....

blogercn
2009/11/25
0
0
转载:do...while(0)的妙用

MTK中有很多有关do...while(0)的应用,刚开始可能有很多人不太明白为什么使用do...while(0),似乎不加do...while(0),该部分的代码也会只执行一次,其实do...while(0)是出于优化代码考虑的.do.....

blogercn
2009/11/25
0
0
malloc和new有什么区别

malloc和new有以下不同: new、delete是操作符,可以重载,只能在c++中使用。 malloc、free是函数,可以覆盖,c、c++中都可以使用。 new可以调用对象的构造函数,对应的delete调用相应的析构...

夏雪冬日
2012/12/11
0
0
char s[0] & do{}while(0)

http://www.newsmth.net mark: struct line { int len; char s[0];}; struct line l = (struct line )malloc(sizeof(struct line) + 某个长度); l->len = 某个长度; 然后l->s随便用了呗... -......

Orion
2011/09/04
0
0
当年自学c++的时候走了很多弯路,今天分享给大家学习经验

本人从事c++ 将近6年的时间,今天给大家分享下学习经验 到今年年底结束,我做c++ 开发已经6年的时间了,现在月薪可以接近三万已经算知足了,但是距离我年薪百万的目标还有很长的路要走,而以...

你的社交帐号昵
05/30
0
0
C语言/C++编程学习:栈的代码实现之数组方案

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你学知识
06/14
0
0
利用 C++ Interop 封装 ISO C++ 对象, 供其他 .Net 语言使用

.Net BCL 支持两种互操作技术,模块 级重用 P/Invoke 和组件级重用COM 互操作, C++/CLI 除了支持以上两种互操作以外,更支持代码级重用, 称为 C++ Interop,本文 仅举例说明这种互操作技术。...

Yong_Luo
2010/10/01
0
0
Linux应用程序Makefile模版

本文在 http://sourceforge.net/projects/gcmakefile/ 的成果上改进得来。 主要修改如下: 1.去掉了说明部分,使得模版更简洁; 模版本身已经具备自说明特性。 2.去掉自动生成目标名称部分;...

索隆
2012/04/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JAVA知识点随心记

1.Switch case具体的支持类型? Q:支持byte、short、char、int基本类型,枚举类型和String类型(JDK7以上支持),四种基本类型的包装类型也支持,但是原因在于触发了自动拆箱,将包装类型拆成了基本...

勤奋的蚂蚁
8分钟前
0
0
NoSQL

一、NoSQL介绍 NoSQL属于非关系型数据,mysql属于关系型数据库。 对于关系型数据库来说,是需要把数据存储到库、表、行、字段里,查询的时候根据条件一行一行地去匹配,当数据量非常大的时候...

人在艹木中
13分钟前
0
0
第17章MySQL主从配置

mysql安装总结 mysql主从准备工作: 准备两台机器,每台机器安装msyql服务,并启动mysql服务 mysql详细安装 1.首先下载二进制免编译的包,下载到/usr/local/src/目录下 2.解压压缩包 3.解压完...

Linux学习笔记
17分钟前
0
0
Redis高可用及分片集群

一、主从复制 使用异步复制 一个服务器可以有多个从服务器 从服务器也可以有自己的从服务器 复制功能不会阻塞主服务器 可以通过服务功能来上主服务器免于持久化操作,由从服务器去执行持久化...

Java大蜗牛
21分钟前
0
0
前端面试题汇总

最近在复习,准备找工作了,特此总结一下前端的相关知识。 1.获取浏览器URL中查询字符的参数: function getQuery(name){    var reg = new RegExp("(^|&)"+name+"=([^&]*)"(&|$));...

凛冬来袭
55分钟前
0
0
可持续发展的学习道路

与其要求别人,不如提升自己 内心渴望进步 经常做出改变现有模式,不断学习 寻找资源,整合资源,不断熟练这种模式 渠道很重要 先打开新世界的航路

狮子狗
59分钟前
0
0
apollox-lua开源项目 示例codepen2

今天在示例上增加了几个功能, 首先添加js array的标准库。 所有js array的方法目前都支持了。 添加查看code模式。 点击查看code可以看到生成的lua代码。默认web模式需要把标准库连接进来, ...

钟元OSS
今天
0
0
javascript性能优化之避免重复工作

javascript最重要也最根本的性能优化标准之一是避免工作,避免工作又包括两点,第一,不做不必要的工作,第二,不做重复的已经完成的工作。第一部分可以通过代码重构完成,第二部分不做重复的...

老韭菜
今天
0
0
缓存穿透、并发和雪崩那些事

0 题记 缓存穿透、缓存并发和缓存雪崩是常见的由于并发量大而导致的缓存问题,本文讲解其产生原因和解决方案。 缓存穿透通常是由恶意攻击或者无意造成的;缓存并发是由设计不足造成的;缓存雪...

Java填坑之路
今天
1
0
项目jar包管理构建工具---Maven

一、what is Maven? 我们来寻找一下官网,里面介绍了maven到底是什么?下面一句话就有讲解到:Apache Maven is a software project management and comprehension tool. Based on the conc...

一看就喷亏的小猿
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部