以前知道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. Ubuntu 重装 mysql

    我另篇blog有提到修改完my.cnf文件后mysql server重新启动失败,就是说mysql server启动不起来了,于是我就想到重装再试试,没想到就好了. 重装mysql之前需要卸载干净,删 ...

  2. ZOJ 3195 Design the city 题解

    这个题目大意是: 有N个城市,编号为0~N-1,给定N-1条无向带权边,Q个询问,每个询问求三个城市连起来的最小权值. 多组数据 每组数据  1 < N < 50000  1 < Q ...

  3. 【转载】rem自适应布局-移动端自适应必备

    原文链接:rem自适应布局-移动端自适应必备 版权所有,转载时请注明出处,违者必究. 由于移动端特殊性,本文讲的是如何使用rem实现自适应,或叫rem响应式布局,通过使用一个脚本就可以rem自适应,不 ...

  4. HTML表单基本格式与代码

    咱们先来看下今天咱们需要学习的内容,理解起来很简单,像我这种英语不好的只是需要背几个单词 在HTML中创建表单需要用到的最基本的代码和格式 <form method="post/get ...

  5. border-raduis 在IE8中的兼容性问题

    border-raduis 是css3新增加的属性,我们运用起来也很方便,效果很好,但是在IE8以及之前的ie版本并不支持这个属性,怎么解决这个问题呢? 1.切成背景 这也是我经常用到的方法,虽然说有 ...

  6. bootstrap快速入门笔记(九)-响应式工具

    一,可用的类   超小屏幕手机 (<768px) 小屏幕平板 (≥768px) 中等屏幕桌面 (≥992px) 大屏幕桌面 (≥1200px) .visible-xs-* 可见 隐藏 隐藏 隐藏 ...

  7. edge animate从入门到放弃

    一.什么是edge animate edge animate这是一款方便网页设计师和前端工程师实现动画交互的一款工具,虽然是adobe出品的,但是属于Flash和H5时代的过渡产物,这一款产品在201 ...

  8. [内存管理]linux X86_64处理器的内存布局图

    linux X86 64位内存布局图

  9. java线程(二)

    线程范围变量 我们知道线程在cpu上的使用权并不是长时间的,因为计算机的cpu只有一个,而在计算上运行的进程有很多,线程就更不用说了,所以cpu只能通过调度来上多个线程轮流占用cpu资源运行,且为了保 ...

  10. POJ 3311---Hie with the Pie(状压DP)

    题目链接 Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as ...