一级棒(Eachfun)
一级棒 - 读书笔记 - C++ Primer - 内存管理之new和delete
RSS订阅
内存管理之new和delete
发表时间:2006-07-19 23:00:42 关键词:C++,MFC,VC,Primer,编程,教程,读书

  林锐博士曾将内存管理比喻为“雷区”(《高质量C++/C编程指南》第44页),内存管理这块难不难?恐怕不好说。“会者不难难者不会”嘛。但是说内存管理这块难以成为“会者”,应该是没有错的。
  程序时时刻刻与内存打交道,只不过以往我们不用考虑,甚至不用知道。所以,所谓“内存管理”,是特指堆内存。
  如果把堆内存和栈内存的使用放在一起考虑,可以降低对内存管理恐惧。
  一、内存的分配:
  int i(100);//栈上分配内存
  int *pi = new int(100);//堆上分配内存
  以上两种分配,都使用了100作为初始值进行初始化,如果是进行类对象的分配,它们还可以指定使用哪个构造函数,比如:
  CString s(s1);//栈上分配内存
  CString *ps = new CString(s1)//堆上分配内存
  这里的s可以是char*指针,也可以是另一个CString对象,它的类型将决定上面这两行语句调用哪一个构造函数。
  在这里,有一点要特别说明,如果要使用默认构造函数,则new语句后面可以用空括号对,而栈内分配的语句切不可用空括号对。如果写成“CString s();”,则并不是定义一个CString对象s,而是定义一个返回值为CString的函数s。
  上面两种分配,也都可以分配对象数组,不同的是,用new操作符在堆内存分配数组时,只能调用默认构造函数。而在栈上分配却可以指定对象成员的初始值。如:
  int a[3] = {1,2,3};//栈上分配内存,int可以换成其它类型名,后面的初始值可作相应调整。
  int *p = new int[3];//不能指定这三个对象的初始值
  二、内存的访问:
  栈内存可以通过对象访问,也可以通过指针访问,堆内存通过指针访问。方法完全相同。
  三、内存的释放:
  栈内存在对象作用域结束后自动释放,堆内存要用delete。
  delete pi;//释放内存
  delete []p;//释放对象数组
  对于释放对象数组,那个空的[]对不可以丢,否则将只释放数组的第一个元素。导致内存泄露。
  有了以上对比,堆内存似乎没有了任何难度。那么内存管理的玄机究竟在哪儿呢?在进行内存分配与释放的时候,有几个注意点要记住:
  1、new操作有可能失败,当系统无法分配需要的内存块时,将返回NULL值,所以在new操作之后,要立即判断pi的值是否为NULL。
  int *pi = new int(100);
  if (pi = NULL) {...}
  2、堆上分配的内存必须delete,而且只可以delete一次。为了保证内存只被delete一次,请务必记住delete以后立即将指针设为NULL:
  delete pi;
  pi = NULL;
  虽然“pi=NULL;”不是必须的,但这是个好习惯。将指针设为NULL既可以防止继续读写该内存,也可以防止再次释放该内存。
  老的C程序员可能忘不了malloc和free函数,它们也可以进行内存的分配与释放。但是C++时代它们已经落伍了。它们只是按请求的字节数进行分配,而不管你用这块内存来干什么。这样做,就等于放弃了类对象的构造与析构。对于很多类来说,这样做是很危险的。

本站特约顾问律师常州东晟律师事务所朱立律师(电话13915029670,QQ646146109)提醒您:
本站文章皆为作者原创,其它媒体(包括但不限于报刊、杂志、网站、电视、电台)未经作者书面许可严禁转载(或部分摘录)!
发表评论
称呼:
QQ:
邮箱:
链接:
内容:
搜索: 百度搜索 Google搜索
Copyright©2000 - 2008 Eachfun.Com, All Rights Reserved 一级棒网络
苏ICP备05080156号
一级棒建站系统 http://www.eachfun.com 一级棒版权所有,未经许可不得商用!