C++基础遗漏:new和delete

我记得当年学习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的内存空间pDescStr
char* pDescStr=new char[nLength]; 
for(int i=0;i<nLength;i++)
{
    pDescStr[nLength-i-1]=pSourceStr[i];
}
//结束前并没有释放pDescStr所指向的内存空间
return pDescStr;
//只是释放了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并非我们想像的那么简单,除了我所提到的用处之外还有不少其他的用处,有待研究。

C++ new delete(二)的更多相关文章

  1. C++中的new与delete(二)

    C++一个对象构造的完整过程为:分配内存和初始化,这也是new关键字所实现的功能,分配内存可通过重载new操作符来实现,系统初始化可通过调用构造函数来完成.我们不能改变new关键字的功能,但可以改变分 ...

  2. django模型——数据库(二)

    模型--数据库(二) 实验简介 模型的一些基本操作,save方法用于把对象写入到数据库,objects是模型的管理器,可以使用它的delete.filter.all.order_by和update等函 ...

  3. c++ 用new创建二维数组~创建指针数组【转】

    #include <iostream> using namespace std; void main() { //用new创建一个二维数组,有两种方法,是等价的 //一: ] = ][]; ...

  4. Java基础(十二)IO输入输出

    一.IO 概述 1.IO 概念 IO:I 代表 Input 输入:O 代表 Output 输出. Java 中 IO 是以流为基础进行输入输出,所有的数据被串行化(保存)写入输出流,或者从输入流读入. ...

  5. hibernate的集中持久化方法的区别

    一.预备知识 在所有之前,说明一下,对于hibernate,它的对象有三种状态,transient.persistent.detached 下边是常见的翻译办法: transient:瞬态或者自由态 ...

  6. IO流(五)__文件的递归、Properties、打印流PrintStream与PrintWriter、序列流SequenceInputStream

    一.文件的遍历 1.需求:对指定目录进行所有的内容的列出(包含子目录的内容)-文件的深度遍历 思想:递归的思想,在递归的时候要记住递归的层次. public class FileTest { publ ...

  7. 黑马程序员——【Java基础】——File类、Properties集合、IO包中的其他类

    ---------- android培训.java培训.期待与您交流! ---------- 一.File类 (一)概述 1.File类:文件和目录路径名的抽象表现形式 2.作用: (1)用来将文件或 ...

  8. mysql触发器使用

    触发器 简要 1.触发器基本概念 2.触发器语法及实战例子 3.before和after区别 一.触发器基本概念 1.一触即发 2.作用: 监视某种情况并触发某种操作 3.观察场景 一个电子商城: 商 ...

  9. ORacle初级题

    一. 选择(每题1分,共15分) 1.在linux系统中,可以通过以下命令查看内核版本(). * A.who B.hostname C.uname -r D.release 2.登入linux系统后, ...

随机推荐

  1. HDU 2077 汉诺塔IV (递推)

    题意:... 析:由于能最后一个是特殊的,所以前n-1个都是不变的,只是减少了最后一个盘子的次数,所以根据上一个题的结论 答案就是dp[n-1] + 2. 上一题链接:http://www.cnblo ...

  2. JDK8 Lamdba表达式转换成Map,value为null问题

    // 将list转换成Map类型 Map<String, String> map = list.stream().collect(Collectors.toMap(Person::getI ...

  3. git 基本命令详细解释

    创建: 2017-04-05 17:04:03         2017-04-24 更新: 2017-05-16 更新: 2017-06-27  完善git remote add  更新: 2017 ...

  4. 介绍一下Extern “C”,它的作用是什么?

    Extern “C”是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数.这是因为C++编译后库中函数名会变得很长,与C生成的不一致,造成C++不能直接调用C函数,加上extren “ ...

  5. hdu5443 【线段树】

    题意: 略 思路: 暴力是可以的O(1e7),这里采用线段树,线段树区间查找O(logn) #include<stdio.h> #include<string.h> #incl ...

  6. python 通过setup.py安装和卸载python软件包

    安装:sudo python setup.py install 卸载:sudo python setup.py install --record log sudo cat log | sudo xar ...

  7. alternatives 命令学习

    最经在捣鼓Cloudera的cdh ,发现里面使用了alternatives命令,由于不懂这个命令,让我走了好多弯路. 现在mark一下 ubuntu 12.04 系统的命令为:update-alte ...

  8. pip查看安装包的可安装版本

    不需要下载或者安装任何其他软件包,你可以指定一个高得离谱的版本号( 不可能有实际安装候选),并且可用的版本将被打印: pip install scrapy==122222 得到信息后指定版本就好了 p ...

  9. oracle 生成随机数

    产生一个介于指定范围之内的38位精度的随机数SQL> SELECT DBMS_RANDOM.VALUE(1, 9999) FROM dual; DBMS_RANDOM.VALUE(1,9999) ...

  10. Qt容器类之三:通用算法

    在<QtAlgorithm>头文件中,Qt提供了一些全局的模板函数,这些函数是可以使用在容器上的十分常用的算法.我们可以在任何提供了STL风格迭代器的容器类上用这些算法,包括QList.Q ...