栈: 是一种连续储存的数据结构, 具有先进后出的性质. 通常的操作有入栈 (圧栈), 出栈和栈顶元素. 想要读取栈中的某个元素, 就要将其之前的所有元素出栈才能完成. 类比现实中的箱子一样.
堆: 是一种非连续的树形储存数据结构, 每个节点有一个值, 整棵树是经过排序的. 特点是根结点的值最小 (或最大), 且根结点的两个子树也是一个堆. 常用来实现优先队列, 存取随意.
先推出两个在 c++ 中很重要的概念 - 堆和栈, 一个简单不同就是存放在堆中的对象会在作用域结束后自动销毁释放内存, 而存放在堆中的对象则需要手动销毁对象来释放内存
先看一看那些是 c++ 中的作用域, 一对花括号就定义了一个作用域. 这就是最典型的作用域.
下图中, 条件语句的 body 也是一个作用域
还有就是在 class 中也定义了一个作用域
我们通过一个示例来讲解, 这里定义类 Entity
然后在自由作用域中实例化一个 Entity, 打断点并运行程序.
F10 一步一步向下执行代码, 当执行到 30 行发现, 创建的对象 e 在离开作用域后自动销毁了.
当使用 new 关键字来创建对象 e 时, 由于给 e 对象分配的内存在堆内存中, 作用域对于堆内存中的的对象无法在离开作用域时将其销毁来释放内存.
我们再举一个例子来进一步说明, 定义一个函数来返回指针数组, 在函数体内创建数组来将其返回. 我们可以试着想一想是否可以通过调用函数来获取数组指针.
我们有两中方案可以解决这个问题. 使用 new 关键字定义数组时, 将其存放到堆内存, 这样就不会在函数作用域结束时释放了.
也可以事先定义数组, 然后将数组引用传入 createArray 函数中, 这样就可以实现在 CreateArray 方法内为数组 array 赋值的效果, 这样同样可以达到 CreateArray 创建数组的功能.
下面介绍一个小技巧, 创建一个 ScopedPtr 类, 然后指向 Entity 类型的指针 m_Ptr 作为私有变量, 在 ScopedPtr 构造函数创建一个指向 Entity 类型的指针. 然后在 Destroy 方法中将 m_Ptr 从堆内存中释放.
由于 ScopedPtr 放在栈内存, 所以在 ScopedPtr 会作用域结束后释放内存, 调用 destroy 方法时会有删除 m_Ptr, 将 m_Ptr 从堆内存中释放
来源: http://www.jianshu.com/p/5b97c51b914b