内存管理

1)正确得到: 正确调用内存分配和释放程序;

2)有效使用: 写特定版本的内存分配和释放程序;

C中用mallco分配的内存没有用free返回, 就会产生内存泄漏, C++中则是new和delete;

new和delete是隐式地调用构造和析构函数的, 而且可以在类内和类外自定义new和delete操作符, 这样带来了复杂性;


条款5 对应的new和delete要采用相同的形式

1
2
3
string *stringArray = 
new 
string[100];
//...
delete 
stringArray;

>stringArray指向的100个string对象中的99个不会被正确地摧毁, 析构函数不会被调用;

new会做两件事: 1) 内存被分配(operator new函数); 2) 为被分配的内存调用一个或多个构造函数;
delete也做两件事: 1) 为将被释放的内存调用一个或多个析构函数; 2) 释放内存(operator delete函数);

删除数组时要使用delete[]:

1
2
3
4
5
string *stringPtr1 = 
new 
string;
string *stringPtr2 = 
new 
string[100];
//...
delete 
stringPtr1; 
// 删除一个对象
delete 
[] stringPtr2; 
// 删除对象数组

在delete非数组时加 [], 结果是不可预测的, 在delete数组时没有 [], 结果也是不可预测; 对于int这样的固定类型, 没有析构函数, 但结果也是不可预测;

Note new对应delete, new[]对应delete[];

当一个类包含指针数据成员, 有多个构造函数时尤其注意, 在所有初始化指针成员的构造函数里采用相同的new的形式, 否则在析构函数中无法确定delet的形式;

Note 对typedef来说也需注意, 为避免混乱, 最好杜绝对数组类型使用typedef; 使用stl的string和vector模板替代;

1
2
3
4
5
typedef 
string AddressLines[4];
string *pal = 
new 
AddressLines;
// 注意"new AddressLines" 返回string*, 和 "new string[4]"返回的一样
delete 
pal; 
// 错误!
delete 
[] pal; 
// 正确

>AddressLines[]->vector<string>;

条款6 析构函数里对指针成员调用delete

大多数情况下, 动态内存分配的类在构造函数里用new分配内存, 在析构函数里用delete释放内存;

1) 每个构造函数里对指针进行初始化, 如果暂时没有内存分配给指针的话, 指针要被初始化为0(NULL, 空指针);
2) 删除现有的内存, 通过赋值操作符分配给指针新内存;
3) 析构函数里删除指针;

在构造和赋值操作过程中出现问题会比较明显, 但是在析构函数里没有正确删除指针, 可能只表现为一点微小的内存泄漏, 不断增长, 最后导致程序crash;

Note 删除空指针是安全的(等于什么都没做);

在写构造函数, 赋值操作符, 或其他成员函数时, 类的指针成员要指向有效的内存或者指向为空, 这样在析构函数中可以简单地delete, 不用检查指针是否new过;

Note 对于没有用new初始化的指针, 就像你永远不会去删除传递进来的指针 [异步的情况下, 可能需要接受外部传递指针的控制权, 在内部删除外部临时new的指针]

使用智能指针可以避免必须删除成员指针, 把成员指针用智能指针对象代替; e.g. stl中的auto_ptr;

Effective C++ 第二版 5)new和delete形式 6) 析构函数里的delete的更多相关文章

  1. Effective Java 第二版 Enum

    /** * Effective Java 第二版 * 第30条:用enum代替int常量 */ import java.util.HashMap;import java.util.Map; publi ...

  2. Effective C++ 第二版 10) 写operator delete

    条款10 写了operator new就要同时写operator delete 写operator new和operator delete是为了提高效率; default的operator new和o ...

  3. Effective C++ 第二版 8) 写operator new 和operator delete 9) 避免隐藏标准形式的new

    条款8 写operator new 和operator delete 时要遵循常规 重写operator new时, 函数提供的行为要和系统缺省的operator new一致: 1)正确的返回值; 2 ...

  4. 《Effective Java第二版》总结

    第1条:考虑用静态工厂方法代替构造器 通常我们会使用 构造方法 来实例化一个对象,例如: // 对象定义 public class Student{ // 姓名 private String name ...

  5. Effective C++ 第二版 17)operator=检查自己 18)接口完整 19)成员和友元函数

    条款17 在operator=中检查给自己赋值的情况 1 2 3 class  X { ... }; X a; a = a;  // a 赋值给自己 >赋值给自己make no sense, 但 ...

  6. Effective C++ 第二版 40)分层 41)继承和模板 42)私有继承

    条款40 通过分层来体现"有一个"或"用...来实现" 使某个类的对象成为另一个类的数据成员, 实现将一个类构筑在另一个类之上, 这个过程称为 分层Layeri ...

  7. Effective C++ 第二版 31)局部对象引用和函数内new的指针 32)推迟变量定义

    条款31 千万不要返回局部对象的引用, 不要返回函数内部用new初始化的指针的引用 第一种情况: 返回局部对象的引用; 局部对象--仅仅是局部的, 在定义时创建, 在离开生命空间时被销毁; 所谓生命空 ...

  8. 《Effective Java 第二版》读书笔记

    想成为更优秀,更高效程序员,请阅读此书.总计78个条目,每个对应一个规则. 第二章 创建和销毁对象 一,考虑用静态工厂方法代替构造器 二, 遇到多个构造器参数时要考虑用builder模式 /** * ...

  9. Effective C++ 第二版 1)const和inline 2)iostream

    条款1 尽量用const和inline而不用#define >"尽量用编译器而不用预处理" Ex. #define ASPECT_R 1.653    编译器永远不会看到AS ...

随机推荐

  1. 解读CSS文本(text)样式

    通过文本属性,您可以改变文本的颜色.字符间距.对齐文本.装饰文本.文本缩进,等等. color: 该属性用于改变文本的颜色,注意区分background-color. Line-height: 该属性 ...

  2. jquery-multiselect在ie6里的一个bug

    在使用jquery-multiselect(一个把下拉框改造成带checkbox的可以多选的控件)时,正常时应该是下面这样:而它在ie6里是下面这样: 其中第一个bug参考‘ie6里png图片不透明’ ...

  3. php 之 PDO数据访问抽象层(0513)

    PDO(PHP Data Objects)是一种在PHP里连接数据库的使用接口. PDO与mysqli曾经被建议用来取代原本PHP在用的mysql相关函数, 基于数据库使用的安全性,因为后者欠缺对于S ...

  4. c# 与 c++ 编译

    C#的所有方法封装在类中,类的方法没有先后之分,无需声明.//而C++必须在函数调用前,由编译器检查参数类型是否合法,所以必须知道函数的原形(protype),所以必须提前声明函数的签名(signat ...

  5. 《javascript权威指南》第9章 例9-8源码

    //创建一个新的枚举类型 //不能使用它来创建该类型的新实例 function Enumeration(nameToValues){ var Enumeration = function(){thro ...

  6. Ubuntu12.04 下svn服务搭建及Windows客户端tortoisesvn的使用

    在Ubuntu服务端搭建apache+svn 在客户端使用Tortoisesvn工具. 第一步 安装SVN $sudo apt-get install subversion 安装成功后系统会自动建立一 ...

  7. hdu 1385 Minimum Transport Cost

    http://acm.hdu.edu.cn/showproblem.php?pid=1385 #include <cstdio> #include <cstring> #inc ...

  8. Wireshark "The NPF driver isn’t running…"(可见的驱动本质上是一个系统服务,使用net start 启动)

    前几天重装系统,装上了windows7 RC系统.昨天开始尝试装上了wireshark 这款很强大的网络监视软件,满心欢喜的打开,可是每次打开都会弹出“The NPF driver isn't run ...

  9. 基本SQL练习题--选课经典例题

    为管理岗位业务培训信息,建立3个表: S (S#,SN,SD,SA) S#,SN,SD,SA 分别代表学号.学员姓名.所属单位.学员年龄 C (C#,CN ) C#,CN 分别代表课程编号.课程名称 ...

  10. 【转】彻底解决INSTALL_FAILED_UPDATE_INCOMPATIBLE的安装错误

    原文网址:http://bbs.9ria.com/thread-245162-1-1.html 利用adb shell进入系统,进入/data/app或者/data/data,删除跟你安装的apk同样 ...