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。这样,系统在回收这个类的实例的内存时,才会完全把其引用的所有堆内存释放掉。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

在类中delete自己会不会有问题??

这个问题很多人都在问,很多人有不同答案,有一点是可以肯定,就是千万别在析构函数中调用delete this,因为会造成死递归(delete this调用后会再次调用析构函数,再次delete this...

c++:(各种)构造函数的调用方式

c++的类中有5种值得注意的基本的函数: 无参构造函数 有参构造函数 拷贝构造函数 赋值函数 析构函数 关于析构函数,需要注意的点在上一篇博客里面 c++: 是否会自动delete? 也提到过了,在这...

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

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

[C/C++][经典探讨]类继承中,通过基类指针delete释放,是否会造成内存泄漏

[序言] 很久不写C/C++技术贴了,算一下自己用C++也有7~8年了,虽然现在用Delphi比较多,但是对C++还是有一份热情.前段时间在CSDN看到一个帖子,让我感到非常失落, 很多人都没有引用...

C++指针delete是否需要判空

这是个老话题了,大家都知道在C++语言中delete一个空指针是安全的。但今天我想讨论的并不是C++标准是否支持delete空指针的操作。且听我慢慢道来... 前几天的检视同事的代码时,发现了一个内...

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

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

类继承中,通过基类指针delete释放,是否会造成内存泄漏

[序言] 很久不写C/C++技术贴了,算一下自己用C++也有7~8年了,虽然现在用Delphi比较多,但是对C++还是有一份热情.前段时间在CSDN看到一个帖子,让我感到非常失落, 很多人都没有引用...

delete未提交rollback是否会改变行号

今天做个试验,delete未提交rollback是否会改变行号? 创建测试表: create table dxmy (id number,name varchar2(100)); 插入数据 ...

【QT】表格控件+qt中没delete是否会内存泄漏

功能截图:表格控件的每一个单元格代表一个item,相互独立。 加入数据如下: 代码实现:1、设置列数 ui->tableWidget->setColumnCount(2);2、设置标题 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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