写出那些不会导致任何内存泄漏的代码。很明显,当你的代码中到处充满了new 操作、delete操作和指针运算的话,你将会在某个地方搞晕了头,导致内存泄漏,指针引用错误,以及诸如此类的问题。 这和你如何小心地对待内存分配工作其实完全没有关系:代码的复杂性最终总是会超过你能够付出的时间和努力。于是随后产生了一些成功的技巧,它们依赖于将内存分配(allocations)与重新分配(deallocation)工作隐藏在易于管理的类型之后。标准容器(standard containers)是一个优秀的例子。它们不是通过你而是自己为元素管理内存,从而避免了产生糟糕的结果。想象一下,没有string和vector的帮助,写出这个:

#include<vector>
#include<string>
#include<iostream>
#include<algorithm>

using namespace std;

int main() // small program messing around with strings
{
  cout << "enter some whitespace-separated words:\n";
  vector<string> v;
  string s;
  while (cin>>s) v.push_back(s);
  sort(v.begin(),v.end());
  string cat;
  typedef vector<string>::const_iterator Iter;
  for (Iter p = v.begin(); p!=v.end(); ++p) cat += *p+"+";
  cout << cat << ’\n’;
}

   你有多少机会在第一次就得到正确的结果?你又怎么知道你没有导致内存泄漏呢?

   注意,没有出现显式的内存管理,宏,造型,溢出检查,显式的长度限制,以及指针。通过使用函数对象和标准算法(standard algorithm),我可以避免使用指针——例如使用迭代子(iterator),不过对于一个这么小的程序来说有点小题大作了。

   这些技巧并不完美,要系统化地使用它们也并不总是那么容易。但是,应用它们产生了惊人的差异,而且通过减少显式的内存分配与重新分配的次数,你甚至可以使余下的例子更加容易被跟踪。早在1981年,我就指出,通过将我必须显式地跟踪的对象的数量从几万个减少到几打,为了使程序正确运行而付出的努力从可怕的苦工,变成了应付一些可管理的对象,甚至更加简单了。

   如果你的程序还没有包含将显式内存管理减少到最小限度的库,那么要让你程序完成和正确运行的话,最快的途径也许就是先建立一个这样的库。

   模板和标准库实现了容器、资源句柄以及诸如此类的东西,更早的使用甚至在多年以前。异常的使用使之更加完善。

   如果你实在不能将内存分配/重新分配的操作隐藏到你需要的对象中时,你可以使用资源句柄(resource handle),以将内存泄漏的可能性降至最低。这里有个例子:我需要通过一个函数,在空闲内存中建立一个对象并返回它。这时候可能忘记释放这个对象。毕竟,我们不能说,仅仅关注当这个指针要被释放的时候,谁将负责去做。使用资源句柄,这里用了标准库中的auto_ptr,使需要为之负责的地方变得明确了。

#include<memory>
#include<iostream>

using namespace std;

struct S {
  S() { cout << "make an S\n"; }
  ~S() { cout << "destroy an S\n"; }
  S(const S&) { cout << "copy initialize an S\n"; }
  S& operator=(const S&) { cout << "copy assign an S\n"; }
};

S* f()
{
  return new S; // 谁该负责释放这个S?
};

auto_ptr<S> g()
{
  return auto_ptr<S>(new S); // 显式传递负责释放这个S
}

int main()
{
  cout << "start main\n";
  S* p = f();
  cout << "after f() before g()\n";
  // S* q = g(); // 将被编译器捕捉
  auto_ptr<S> q = g();
  cout << "exit main\n";
  // *p产生了内存泄漏
  // *q被自动释放
}

   在更一般的意义上考虑资源,而不仅仅是内存。

   如果在你的环境中不能系统地应用这些技巧(例如,你必须使用别的地方的代码,或者你的程序的另一部分简直是原始人类(译注:原文是Neanderthals,尼安德特人,旧石器时代广泛分布在欧洲的猿人)写的,如此等等),那么注意使用一个内存泄漏检测器作为开发过程的一部分,或者插入一个垃圾收集器(garbage collector)。

Bjarne:如何对付内存泄漏?相关推荐

  1. iOS 对付内存泄漏,来说说我的调试方法

    2019独角兽企业重金招聘Python工程师标准>>> 苹果在iOS5推出了ARC(自动引用计数)技术,此模式下编译器会自动在合适的地方插入retain.release.autore ...

  2. 一个跨平台的 C++ 内存泄漏检测器

    From:http://www.ibm.com/developerworks/cn/linux/l-mleak2/index.html 内存泄漏对于C/C++程序员来说也可以算作是个永恒的话题了吧.在 ...

  3. php 在对象中递归 坑,PHP_PHP对象递归引用造成内存泄漏分析,通常来说,如果PHP对象存在递 - phpStudy...

    PHP对象递归引用造成内存泄漏分析 通常来说,如果PHP对象存在递归引用,就会出现内存泄漏.这个Bug在PHP里已经存在很久很久了,先让我们来重现这个Bug,示例代码如下: class Foo { f ...

  4. [JS] 闭包与内存泄漏

    一句话总结闭包:函数里套函数,函数返回函数. 内存泄漏:每次外部函数执行的时候,外部函数的引用地址不同,都会重新创建一个新的地址.但凡是当前活动对象中有被内部子集引用的数据,那么这个时候,这个数据不删 ...

  5. android释放acitity内存,Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  6. C语言中的指针和内存泄漏

    对于任何使用 C 语言的人,如果问他们 C 语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏.这些的确是消耗了开发人员大多数调试时间的事项.指针和内存泄漏对某些开发人员来说似乎令人畏惧,但 ...

  7. 初步判断内存泄漏方法

    有时候,内存泄漏不明显,或者怀疑系统有内存泄漏,我们可以通过下面介绍的方法初步确认系统是否存在内存泄漏. 首先在Java命令行中增加-verbose:gc参数, 然后重新启动java进程. 当系统运行 ...

  8. 野指针与内存泄漏那些事

    野指针:不是NULL指针,是指向垃圾内存的指针 野指针成因: 1.指针变量没有被初始化:指针变量在创建时同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存. 2.指针p被free或者d ...

  9. 介绍两个非常好用的Javascript内存泄漏检测工具

    内存泄漏对开发者来说一般很难检测因为它们是由一些大量代码中的意外的错误引起的,但它在系统内存不足前并不影响程序的功能.这就是为什么会有人在很长时间的测试期中收集应用程序性能指标来测试性能. 最简单的检 ...

最新文章

  1. 给你总结了这些对付幂等性的套路
  2. Centos7下vim最新版本安装
  3. 每天进步一点点017
  4. 如何去掉子窗体的关闭按钮.右上角的那个X
  5. flask—wtforms
  6. php1008打印机驱动器,hp laserjet p1008打印机驱动
  7. android 界面置顶,Android实现界面滚动时顶部部分内容置顶(附源码)
  8. Flutter Text控件在不同手机上不居中的问题
  9. 「2019.7.22 考试」AC和WA0一步之遥
  10. JAVA的jdk1.8中文文档
  11. vscode如何设置自动保存
  12. 《东方巨龙》一首能感动所有中国人的歌,上榜一周点播过百万!
  13. 如何克服焦虑,不安,紧张
  14. 神经网络与深度学习学习笔记(一)——基本概念
  15. 第一批冯·诺依曼计算机
  16. 流畅的Python读书笔记
  17. 转载-FileZilla Server源码分析(1)
  18. 计算机游戏本和商务本的区别,游戏本和商务本的区别有哪些
  19. QT入门系列(6) 生成UUID
  20. numpy PIL tensor之间的相互转换

热门文章

  1. java加法器_javacc例子:加法器
  2. 不会自动更新了_手机老是自动更新系统?不想频繁更新,不同手机怎么设置好?...
  3. 安卓10省电还是费电_iOS 13省电教程:关掉这8个功能iPhone多用3小时
  4. 状态码202_HTTP状态码大全
  5. python数学建模可视化_数学建模之流程图和数据可视化
  6. Nginx四层负载均衡模块添加
  7. Hystrix仪表盘解释
  8. 用注解还是用xml 配置?
  9. Spring IoC容器:BeanFactory和ApplicationContext谁才是Spring IoC容器
  10. MapReduce-流量统计求和-Reducer和JobMain代码编写