new和delete必须成对出现吗?【网上集合贴+个人总结】
new和delete必须成对出现吗?【网上集合贴+个人总结】
1.从内存泄露与否的角度考虑
new 和 delete不一定要成对出現。理论上是這樣的。但是从习惯上來說,new delete成對出現是一個好的習慣。爲什麽說不一定要成對出現呢?
这个问题在csdn上有一個牛人写过很长的文章,不知道有沒有人还能找到?我記得大概是這個意思。
(1)认为一定要成对出現的,主要是因为动态分配内存之后,如果不释放,会造成内存泄露。
(2)但是,实际上并不总是如此。从操作系统角度上說,内存不能释放,是因为原先指向該内存块的指针丟失了,(比如該指針指向了另一块内存)。这样的情況下,才会造成内存泄露。但是,如果使用了new分配了一块内存,但是指向該内存的指针一直在,一直指向該内存,那麽在程序结束的時候,系統会自动把該指針指向的内存释放掉,從操作系統角度上說,並沒有造成内存洩露。
所以,new和 delete客观的來説,並不一定需要成對出現。我们对内存泄露的真正含義理解的並不是很正确。
這是我看了那個牛人的文章后的体会,那篇文章中有不少例子和數据,還有编译結果解释。非常好,可惜我記不得題目了,沒找到,在這裡說說我的理解。
2.某选择题选项B、D
B,若P的类型由A强制转换为void*,那么执行语句delete P*时,类A的析构函数不会被调用
D,执行语句 A*P=new A[100]时,类A的构造函数只会被调用一次
- class CBase
- {
- public:
- CBase() { cout <<"CBase is running!\n";}
- ~CBase() { cout <<"~CBase() is running!\n";}
- };
- int main()
- {
- //选项B错误
- CBase * pBase = new CBase; //调用构造函数
- void * pVoid = (void *)pBase;
- delete pVoid; //肯定不會調用类A的析构函数
- //选项D错误
- CBase *pBaseN = newCBase[100]; //调用构造函数100次
- delete []pBaseN; //调用析构函数100次
- return 0;
- }
3. C++内存分配之NEW DELETE
1)new 和 delete 必须成对出现;——此处观点值得商榷
2)new底层调用操作系统堆内存管理函数HeapAlloc来分配堆内存;
3)delete操作符底层调用API接口函数HeapFree来释放堆内存;
数据的3种存储方式。
1。静态区:全局变量或者使用static约束的变量;
2。堆:程序执行时分配的内存;如new操作所分配的动态内存
3。栈:函数调用,局部变量。
以上3种方式的区别:注意,堆上分配的内存不会被操作系统自动回收。
以下为常见的动态内存调用和销毁:
语句一: int * pt;
语句二: pt = new int;
语句三: delete pt;
分步详解:
语句一:你声明了一个pt指针,四个字节,放在栈里面的(pt为局部变量,所属栈内存区域);
语句二:你new了一个int形的数据放在堆里面,再把这个数据的地址赋给pt。(动态分配内存,所属堆内存区域);
语句三:把pt指向的地址所占的内存释放掉。
1.释放的就是堆上面的那个int(动态销毁内存,所属堆内存区域数据销毁)
2.pt还是存在的,还在栈里面。不过你查它的值时,变成了null。(pt为局部变量,所属栈内存区域,由操作系统自行销毁)。
如果能够明白以上内容,就可以避免编程过程中的许多问题和疑惑。
4. 实例角度分析
我记得当年学习C++基础的时候,老师曾经告诉我们:一般来说new和delete要成对出现,在使用完new申请的内存后要马上释放。我相信持这种说法的人不止我们老师一个人,养成良好的内存使用习惯固然重要,但如果因此就认为new和delete必须成对出现,使用完new得到的空间后就要马上用delete释放的话,就有点“大材小用”了,相信C++提供这一由用户控制的内存控制方法也不是只限于如此的使用方法。
正确灵活的,或许也是“高级”的使用方法,是在A处使用new申请一块内存,用一个指针指pA向它,之后在B处用指针pB指向pA所指向的空间,释放指针pA本身,接着释放pB所指向的内存空间,最后释放指针pB本身。
以下的代码是本过程的一个例子:
- #include<iostream.h>
- #include<string.h>
- char* ReverseString(char* pSourceStr,int nLength)
- {
- //这里在堆上动态申请了一个长度为nLength的内存空间pDescStr2
- char* pDescStr2=new char[nLength];
- for(int i=0;i<nLength;i++)
- {
- pDescStr2[nLength-i-1]=pSourceStr[i];
- }
- //结束前并没有释放pDescStr2所指向的内存空间
- return pDescStr2;
- //只是释放了pDescStr这个指针
- }
- void main()
- {
- char pSourceStr[]={"abcdefghijk"};
- cout<<"The source string: \t"<<pSourceStr<<endl;
- //新建一个指向ReverseString()函数中申请到的内存的指针
- char* pDescStr=ReverseString(pSourceStr,strlen(pSourceStr));
- cout<<"The desc string: \t"<<pDescStr<<endl;
- //在这里释放ReverseString()函数中申请到的内存
- delete[] pDescStr;
- //清除pDescStr指针,以免在今后的使用中出现溢出
- pDescStr=NULL;
- }
从上面的例子可以看出,new和delete并没有在同一个函数中出现,但是很明显这样做没有造成内存泄露(memory leak)。
或许这样使用new和delete有点小儿科,达到ReverseString()函数的目的完全可以不必使用new和delete。我认为new和delete最大的用武之地是在线程通信和进程通信中:比如线程A要向线程B投递一条信息,并要求不等线程B做出反应线程A就要马上进行后面的操作,也就是要求使用PostMessage(...)函数来投递消息,而且发送的消息内容存储在一个50K或者更大的内存空间中,那就必须使用new和delete了,也就是在线程A中用new准备好这样一个庞大的消息,之后把指针发送给进程B,进程B在处理完消息之后用delete释放这块内存。
总而言之,new和delete并非我们想像的那么简单,除了我所提到的用处之外还有不少其他的用处,有待研究,希望与大家探讨。
http://blog.csdn.net/laoyang360/article/details/7765308
new和delete必须成对出现吗?【网上集合贴+个人总结】的更多相关文章
- 很多人以为 connect 和 disconnect 应该像 new 和 delete 一样成对出现 这是错误的(只要 sender 或 receiver 其中之一不存在了,connect 会自动失效。QObject::connect 函数是线程安全的)
其实我写文章也是边查资料边编辑的 有时候是怕自己的阐述不严谨,有时候是怕自己重复造轮子 就像有些人不停的教大家QLabel QDialog QWidget 个人是不屑的 命令模式 用 Qt's Und ...
- asp.net mvc(一) ----------简单封装成通用的List<T>集合
asp.net mvc(一) 这些天开始学习asp.net mvc,用传统的asp.net已经快四的年了,刚开始接触asp.net mvc确认感觉有点不适应,主要体现在asp.net mvc的实现上. ...
- 条款16:成对使用new和delete时,采取相同的形式
问题聚焦: 我们都知道,new和delete要成对使用,但是有时候,事情往往不是按我们预期的那样发展. 对于单一对象和对象数组,我们要分开考虑. 遇到typedef时,也需要搞 ...
- Effective C++(16) 成对使用new和delete时要采取相同的形式
问题聚焦: 我们都知道,new和delete要成对使用,但是有时候,事情往往不是按我们预期的那样发展. 对于单一对象和对象数组,我们要分开考虑 遇到typedef时,也需要 ...
- Android项目实战(二十四):项目包成jar文件,并且将工程中引用的jar一起打入新的jar文件中
前言: 关于.jar文件: 平时我们Android项目开发中经常会用到第三方的.jar文件. 其实.jar文件就是一个类似.zip文件的压缩包,里面包含了一些源代码,注意的是.jar不包含资源文件(r ...
- new和delete malloc和free
程序中动态分配的对象存放在自由存储区(free store)或堆(heap). C语言程序使用一对标准库函数malloc和free在自由存储区中分配存储空间,而C++语言则使用new和delete表达 ...
- 关于new 和delete
这是百度知道上的答案,感觉讲的很生动形象,接下来要搞清楚的是new是关键字还是函数,new可以重载吗? 你想弄懂这个问题,首先你要弄清楚数据的3种存储方式. 1.静态区: 全局变量. 2.堆: 程序执 ...
- 浅谈new/delete和malloc/free的用法与区别
每个程序在执行时都会占用一块可用的内存空间,用于存放动态分配的对象,此内存空间称为自由存储区或堆. 一.new和delete用法 如下几行代码: int *pi=new int; int *pi=ne ...
- Electron把网页打包成桌面应用并进行源码加密
前言 最近想把自己用html+css+js做的网页界面打包成桌面应用,网上一搜,发现Electron是一个不错的选择,试了试,发现效果真的不错.这里记录一下打包过程以作记录,便于自己以后查看学习. 一 ...
随机推荐
- TensorFlow 实战(五)—— 图像预处理
当然 tensorflow 并不是一种用于图像处理的框架,这里图像处理仅仅是一些简单的像素级操作,最终目的比如用于数据增强: tf.random_crop() tf.image.random_flip ...
- [Erlang 0057] Erlang 排错利器: Erlang Crash Dump Viewer
http://www.cnblogs.com/me-sa/archive/2012/04/28/2475556.html Erlang Crash Dump Viewer真的是排错的天兵神器,还记得我 ...
- 【心情】2016ICPC青岛站打铁记
Day0 下午到的青岛; 然后就在下面这两个地方转了很久:一直找不到公交站台 路上还看到了一个类似堡垒的东西:感觉屌屌的. 然后在落日的余晖下:我们找到了公交站台; 路上不知道他们在讨论什么:GPS什 ...
- Internet protocol optimizer
A method for optimizing the throughput of TCP/IP applications by aggregating user application data a ...
- 从Client应用场景介绍IdentityServer4(三)
原文:从Client应用场景介绍IdentityServer4(三) 在学习其他应用场景前,需要了解几个客户端的授权模式.首先了解下本节使用的几个名词 Resource Owner:资源拥有者,文中称 ...
- C#颜色对照使用表
这篇文章来来源于C# Color Table,这里是我翻译的中文版本,其中已经加上了我的一些理解和注释.翻译这篇文章的原因是我在写C#程序的时候发现,C#自带的颜色种类极多(详见下表),如果没有直观的 ...
- 《Java并发编程实战》第十二章 测试并发程序 读书笔记
并发测试分为两类:安全性测试(无论错误的行为不会发生)而活性测试(会发生). 安全測试 - 通常採用測试不变性条件的形式,即推断某个类的行为是否与其它规范保持一致. 活跃性測试 - 包含进展測试和无进 ...
- Method for finding shortest path to destination in traffic network using Dijkstra algorithm or Floyd-warshall algorithm
A method is presented for finding a shortest path from a starting place to a destination place in a ...
- 在服务器中无法自宿主启动一个webapi项目,引出查看系统端口是否被占用
在windows server下启动一个webapi的.net core项目报错 如下图: 让我以为服务器还需要别的配置.后来发现原来是线程被占用了. 在windows下查看某线程是否被占用的命令如下 ...
- HDU 4279 Number(2012天津网络游戏---数论分析题)
转载请注明出处:http://blog.csdn.net/u012860063? viewmode=contents 题目链接:pid=4279">http://acm.hdu.edu ...