内存管理

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;

最新文章

  1. 配置oozie4.10+hadoop2.5.2
  2. 马克飞象 Markdown 使用和学习
  3. overflow:hidden清楚浮动的影响
  4. Linux测试环境部署jdk(一)
  5. jQuery.validator 验证规则详解
  6. CCF 模拟B 无脑循环+输入输出外挂
  7. 《C与指针》第七章练习
  8. alt属性
  9. AngularJS 中的 Promise 和 设计模式(转)
  10. 在Dynamics CRM 2015中通过3CX插件(以及3CX windows phone)拨出电话
  11. Http 协议Header
  12. android ScrollView滚动距离和判断滚动停止状态
  13. 蓝牙RSSI计算距离
  14. hdoj 1054 Strategic Game【匈牙利算法+最小顶点覆盖】
  15. MVC缓存,使用数据层缓存,添加或修改时让缓存失效
  16. Git 如何回到过去,然后 再 回到将来
  17. XML Dtd Schema
  18. $.each()方法详解
  19. JAVA RSA非对称加密详解[转载]
  20. mysql生成数据字典

热门文章

  1. js判断一个变量是否为数组的解决方案
  2. 解决ie6显示透明图的问题
  3. 汉诺塔问题C++实现
  4. angular+bootstrap分页指令案例
  5. How to run Tomcat without root privileges? 常规用户使用tomcat的80端口
  6. OpenJTAG+Eclipse 3.5+GDB+Mini2440图文教程
  7. 【转】 boot.img的解包与打包
  8. Android App Widget的简单使用
  9. bzoj4033
  10. Delphi 调试 通过BreakPoint