以前知道C/C++有assert之后,我想知道assert会不会造成内存泄漏,于是我做了一个测试:

#include <iostream>
#include <fstream>
#include <cassert>
using namespace std; class A
{
public:
A();
~A();
}; int main()
{
A a;
assert(false); // let the program crash
return ;
} A::A()
{
ofstream fout("test.txt");
fout << "A constructed\n";
fout.close();
} A::~A()
{
ofstream fout("test.txt", ios_base::app);
fout << "A destructed\n";
fout.close();
}

如果想要直接检测是否会有内存泄漏,是很难的,一般都需要借助一些相关软件的帮助。因此这里我们检测的是类的析构函数是否被调用,而析构函数(和构造函数)会向文本文件输出信息。程序运行完毕后,检查该文本文件,如果有A destructed这句话,就表示析构函数被调用了。

注意这里使用的是输出信息到文件而不是控制台。因为如果是控制台你是来不及看到相应消息的,除非暂停程序。(个人喜好问题)

还有一个需要注意的点(在A::~A()中):

ofstream fout("test.txt", ios_base::app);

因为构造函数会打开test.txt并输出,为了保留原来的内容并在文本末尾追加信息,使用了ios_base::app。

那么运行情况如何?

运行程序,和预期一样,弹出了错误框,程序停止。检查一下输出的test.txt,内容如下:

A constructed.

没有见到A destructed,说明构造函数根本没有被调用!对于A类还没什么,但对于STL的string、vector、map这些类来说,它们new的内存会在析构函数里delete,这不就会造成内存泄漏吗?!

是的,没错。

这时就需要Stack Overflow了。我刚刚在上面查到了一篇文章,看来以后要多上上Stack Overflow。

这是Stack Overflow上的回答:

1.

Assert on failure, writes the error to stderr and calls abort(). which unlike exit() doesn't execute the functions registered with atexit(), nor does it call destructors.
Hence, none of your destructors, clean-up code etc can be called. So it is up to the OS, as the memory isn't freed by the program, before its "unexpected" termination.

This is probably by design, as calling destructors might result in some further error. It terminates at that failed assert, executing no further code.

Assert失败时,将错误输出到stderr然后调用abort()。和exit()不同,abort()不执行atexit()注册的函数,或者调用析构函数。因此,你的析构函数、清理代码都不会被执行。所以这就需要靠OS(操作系统)了,因为内存不是在“意外的”结束之前由程序释放的。

这也许是故意设计的,因为调用析构函数可能会出现更多的错误。它(指程序)在失败的assert处停止,不再执行更多代码。

2.

The memory stays allocated as the assert failure brings down your program.

As part of destroying the process, any modern desktop OS will reclaim the memory. Some embedded operating systems might not be able to do this, although I don't have the name of one on hand.

You can detect memory that has to be reclaimed by the OS this way by using a utility such as Valgrind.

Assert失败并使你的程序崩溃时,内存仍然保留着。

作为毁灭进程的一部分,任何现代桌面OS都会收回这些内存。有些嵌入的操作系统(不知道有没有翻错)可能不能这么做,虽然我举不出这样的OS的名字。

你可以使用一个像Valgrind一样的工具检测因为这种原因需要被OS收回的内存。

--------------------------------------------------------------------------------

看完这些答案,说明了一个事实:assert确实会造成内存泄漏。但也不必太担心,通常操作系统都会自动回收这些分配的内存(较老的就不会)。

Assert与内存泄漏的更多相关文章

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

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

  2. VS2005内存泄漏检测方法[转载]

    一.非MFC程序可以用以下方法检测内存泄露: 1. 程序开始包含如下定义: #ifdef _DEBUG #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __ ...

  3. (转)从内存管 理、内存泄漏、内存回收探讨C++内存管理

    http://www.cr173.com/html/18898_all.html 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟 ...

  4. c++内存泄漏处理(积累)

    写c++程序时,常常会出现内存泄漏的问题,这里从网上找了一种非常麻烦的方法:假设想找到每一个cpp文件的内存泄漏,都必须在每一个cpp加上例如以下代码: #include <crtdbg.h&g ...

  5. C++中内存泄漏的检测方法介绍

    C++中内存泄漏的检测方法介绍 首先我们需要知道程序有没有内存泄露,然后定位到底是哪行代码出现内存泄露了,这样才能将其修复. 最简单的方法当然是借助于专业的检测工具,比较有名如BoundsCheck, ...

  6. [C]C语言中的指针和内存泄漏几种情况

    引言 原文地址:http://www.cnblogs.com/archimedes/p/c-point-memory-leak.html,转载请注明源地址. 对于任何使用C语言的人,如果问他们C语言的 ...

  7. C/C++的内存泄漏检测工具Valgrind memcheck的使用经历

    Linux下的Valgrind真是利器啊(不知道Valgrind的请自觉查看参考文献(1)(2)),帮我找出了不少C++中的内存管理错误,前一阵子还在纠结为什么VS 2013下运行良好的程序到了Lin ...

  8. C语言中的指针和内存泄漏几种情况

    引言 原文地址:http://www.cnblogs.com/archimedes/p/c-point-memory-leak.html,转载请注明源地址. 对于任何使用C语言的人,如果问他们C语言的 ...

  9. 内存泄漏(memory leak)和内存溢出

    1. 什么是内存泄漏(memory leak)? 指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况.内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存 ...

随机推荐

  1. 程序设计 之 C#实现《拼图游戏》 (下) 原理篇

    前言:在 http://www.cnblogs.com/labixiaohei/p/6698887.html 程序设计 之 C#实现<拼图游戏>(上),上传了各模块代码,而在本文中将详细剖 ...

  2. VUE进阶(路由等)

    初级教程:http://www.cnblogs.com/dmcl/p/6137469.html VUE进阶 自定义指令 http://cn.vuejs.org/v2/guide/custom-dire ...

  3. view测量

    一.测规格是由测量模式mode和测量大小size组成的,size好说,那测量模式mode代表什么含义呢.由上面的代码可知,测量模式有三类:    UNSPECIFIED    父控件不对你有任何限制, ...

  4. VS2003"无法启动调试 没有正确安装调试器"的解决方法

    在用VS2003做项目的时候,经常调试程序,但是有时候回出现如下问题“无法启动调试,没有正确安装调试器,请运行安装程序或修复调试器”.第一次碰到还以为是运气不好,就重新用vs2003安装程序重新修复了 ...

  5. python基本数据类型——set

    一.集合的定义 set集合,是一个无序且不重复的元素集合. 集合对象是一组无序排列的可哈希的值,集合成员可以做字典中的键.集合支持用in和not in操作符检查成员,由len()内建函数得到集合的基数 ...

  6. Printk与sched_clock_init的一点分析

    在分析Linu内核启动的过程中,发现一段"不平常"的日志,感觉产生这段日志的代码肯定是"不可思议"的.因此就大致分析了一下: 日志如下: [ 0.000000] ...

  7. office web apps 部署-搭建office web apps服务器

    二.搭建office web apps服务器 相关文件可以去焰尾迭分享的百度网盘下载,下载地址:http://pan.baidu.com/s/1o6tCo8y#path=%252Foffice%252 ...

  8. 关于v-model、v-for、v-on的用法

    展示Holle Vue     window.onload = function(){         var box = new Vue({             el:'#div',      ...

  9. 单例模式——Java EE设计模式解析与应用

    单例模式 目录: 一.何为单例 二.使用Java EE实现单例模式 三.使用场景 一.何为单例 确保一个类只有一个实例,并且提供了实例的一个全局访问点 1.1 单例模式类图               ...

  10. 2017云计算开源峰会 你是想听Linux谈开源还是想听OpenStack谈开源?

    2017年,善于把握机遇的企业们不是正在开源,就是走在去开源的路上-- 开源是不是就意味着免费? 开源企业就是要当"活雷锋"? 开源项目究竟如何运作?如何参与开源社区? 如何获得最 ...