c++: 是否会自动delete?

原创 2017年03月01日 16:57:49

一直以来对于C++内存管理部分存在一些小疑问,尤其是涉及到内存泄漏的知识,我觉得还是有必要提出来,以加深印象。


问题1:new了一块内存,一定要手动delete吗?什么时候系统会自动帮助我们delete?

回答:首先C++内存区域分为5个:

  • 全局区(静态区)
  • 常量区
  • 程序代码区

    不过我们使用的,一般都是栈、堆。比如以下这段代码:

#include <iostream>
#include <string>
using namespace std;


class Node {
public:
    Node(int id) {
        cout << "Constructor: " << id << endl;
        this->id = id;
    }

    ~Node() {
        cout << "Destructor: " << this->id << endl;
    }

private:
    int id;
};


int main() {
    Node node1(1);
    Node* node2 = new Node(2);

    // ...do something

    return 0;
}

需要说明的无非就是,node1是在栈上分配的,而node2则使用了堆内存。这里有个结论:对于栈上分配的变量、对象,程序结束的时候,由系统来回收内存;而堆上分配的内存,则需要程序员自行管理,最后一定要记得delete来显式释放堆内存。也就是说,new和delete一定要成对出现。

对于上面这个例子,输出结果是:

Constructor: 1
Constructor: 2
Destructor: 1

node2占用的堆内存没有得到delete,它的destructor也就没有调用。这样,内存泄漏就发生了,我们在Linux系统上可以使用Valgrind这个工具来检测c/c++程序的内存泄露,或者分析内存的使用情况。使用命令:

valgrind –tool=memcheck –leak-check=full ./out
Valgrind的检测结果

可以看到,在“defintely lost”这一行显示有4个byte的内存发生泄漏了,对应的就是一个Node(即node2)的大小。


问题2:Destructor的作用是什么?什么时候需要写destructor?

回答:简单来说,析构函数就是释放本对象占用的内存,避免内存泄漏的。一般来说,我们在析构函数中写代码,是为了在释放本对象之前,释放其成员变量所使用的堆内存。所以,有时候,析构函数的函数块内可以什么都不写,但有时候就必须写,具体看以下:
(1)当我们定义的类中的成员没有指针变量(及其申请的对象),比如用的都是基本类型:int、char等,或者已经完美封装的STL类型:string、vector、list的时候,可以不写析构函数。因为对于基本类型,是分配在栈上,程序结束后会自动回收;而对于STL类型,如string类,就算内部(给char数组)动态分配了堆内存,但是STL已经帮我们写好它的destructor了,在它的destructor中给char数组delete;而且,string对象是在栈上分配的。所以,程序结束后,系统会帮我们回收这个string对象。
(2)如果类成员中存在指针变量,在constructor或者别的成员函数中分配了内存,那么必须在destructor中delete。这样,系统在回收这个类的实例的内存时,才会完全把其引用的所有堆内存释放掉。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/VitaLemon__/article/details/59110409

new/delete 详解

new 和 delete 是 C++ 用于管理 堆内存 的两个运算符,对应于C语言中的 malloc 和 free,但是malloc和free是函数,new 和 delete 是运算符。...
  • hihozoo
  • hihozoo
  • 2016-05-18 14:31:12
  • 10509

C++什么时候用delete

在C#、Java這種managed語言,因為有garbage collection,所以完全不用考慮free()或delete,但在C/C++,有時候要delete的,有時又不用,到底哪些改delet...
  • foodvc
  • foodvc
  • 2008-11-28 17:58:00
  • 3386

c++详解【new和delete】

说起new和delete,了解过c++的人应该都知道吧,它是用来分配内存和释放内存的两个操作符。与c语言中的malloc和free类似。 c语言中使用malloc/calloc/realloc/fr...
  • xxpresent
  • xxpresent
  • 2016-11-21 09:22:34
  • 3303

C++ 常见崩溃问题分析

一、前言 从事自动化测试平台开发的编程实践中,遭遇了几个程序崩溃问题,解决它们颇费了不少心思,解决过程中的曲折和彻夜的辗转反侧却历历在目,一直寻思写点东西,为这段难忘的经历留点纪念,总结惨痛的教训带...
  • kyfvc
  • kyfvc
  • 2012-01-08 16:40:36
  • 30397

C ++ delete 和delete[]

【原文引用如下】: C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。  关于 new...
  • rushkid02
  • rushkid02
  • 2012-05-15 10:58:05
  • 4100

new 出来的存储空间(如果不使用delete),系统会自动回收?

http://blog.sina.com.cn/s/blog_4aecb7bd010006gb.html new 出来的存储空间(如果不使用delete),系统会自动回收?! (2006-11-12 ...
  • DeepIT
  • DeepIT
  • 2011-04-25 15:43:00
  • 1757

C++中使用delete 需要注意的两个问题

1.  每次调用delete后一定要将对应的指针设置为NULL,要养成这样一个好习惯。为了保证每次delete后就执行赋值为NULL的习惯,可以定义单独的函数来做。下面是转载的一种方案:(http:/...
  • pendle
  • pendle
  • 2010-09-15 18:06:00
  • 3966

gdb - 暂停/恢复程序执行

GDB - 暂停/恢复程序执行      在使用GDB调试程序的时候,经常需要暂停程序,以查看程序执行情况和上下文。GDB 提供了多种暂停程序的方式,包括 break point, wat...
  • paul123456789io
  • paul123456789io
  • 2017-01-13 13:42:38
  • 1478

gdb(二)暂停或恢复程序的运行

一 暂停程序的运行: (一)GDB的暂停方式:断点(BreakPoint)、观察点(WatchPoint)、捕捉点(CatchPoint)、信号(Signals)、线程停止(Thread Stops...
  • first_wolf
  • first_wolf
  • 2013-06-07 20:06:03
  • 3220

delete 指针之后 ,只是释放了指针指向的内存空间,指针不会自动置为NULL,还有delete 遇到指针为NULL时不会调用析构函数

#include using namespace std; class A { public:         A( void )        {              ...
  • imxiangzi
  • imxiangzi
  • 2015-10-22 16:02:46
  • 1042
收藏助手
不良信息举报
您举报文章:c++: 是否会自动delete?
举报原因:
原因补充:

(最多只允许输入30个字)