C++基础学习笔记(五):堆与栈

写在开头

在最近学习编程时,总是会思考一些细枝末节的问题,这些问题总是会扰乱我的心绪,可能是由于之前没有认真的探究,或者是曾经探究过,但是已经忘掉了,今天一直在脑海里思考的问题是,为什么有的时候需要用new来创建一个对象或数组或结构体呢?当然,不同的老师可能针对这个问题已经提过不止一次了,但是亲身实践才发现,这些细节也足够让人纠结,所以今天就把学到的内容进行一个总结,以备不时之需。

  • 堆与栈的概念
    同意堆与栈的区别中对不同场景下的堆栈定义区别:

(1)程序内存布局场景下,堆与栈表示的是两种内存管理方式;
(2)数据结构场景下,堆与栈表示两种常用的数据结构。

  • 堆与栈的定义
    在编程初期,我们一直都在与栈打交道,从计算导论与程序设计这门课开始,就已经开始接触这一概念了,那么栈最基础的知识就不再多提了,需要强调的是栈在物理上的地址空间是连续的,而且后申请的变量具有更小的地址值,而且栈中的数据生命周期与函数相同,函数调用结束了,栈也就随之删除。
    但是堆有与栈不相同的内涵,在堆上的数据地址与申请的顺序没有严格的匹配关系,是随机申请的空间,只要不主动释放堆的数据,就会一直存在,所以如果大量申请堆中数据并且没有释放,就会出现内存泄漏的问题。但是释放堆的内存也要注意,应该对所要释放的指针进行判空操作,值得注意的是,老师课上曾强调过在delete指针前,要判断指针是否为空,但是查阅资料后发现好像并不需要这么做,因为g++中会自动判断要释放的指针是否为空,总结来说就是,可以判断,但没必要。但是为了避免释放的指针成为野指针,要把指针赋为NULL
  • 堆与栈的区别
    其实说了不少,堆与栈的区别在上面就已经体现出来了。总结来说就是,在需要开辟大量内存空间或者希望控制数据的生存周期时,就应该通过堆,这也是在接下来的数据结构联系中需要注意的细节。

下面是以前曾经用过的动态申请二维数组的方法作为范例:

    //动态申请一个m行n列的整形数组
    int **p = new int *[m];
    for(int i = 0;i < m; ++i)
        p[i] = new int[n];
    //内存释放
    for(i = 0;i < m; ++i)
        delete[] p[i];
    delete[] p;

事实上,使用C++的STL中vector可以更加方便的完成二维数组的动态申请:

//注意int后面的> >之间要有空格,否则会认为是重载的">>"
vector  > p(m,vector(n));

你可能感兴趣的:(C++基础学习笔记(五):堆与栈)