/*用指针p存储堆中的空间时,在将第二块内存空间赋给p之前,我们要释放p原来指向的内存空间,
这样才不会造成内存泄漏,不然的话p原来记录的内存空间就找不到了,而且也无法再次利用
注意:你在使用new以后,加入不再使用该块内存空间,那么一定要用delete来释放它*/ /*堆中可以保存变量,也可以保存对象,我们可以将对象保存在堆中,通过指针来访问它 */ /*创建对象的时候会自动调用类的构造函数来初始化对象的成员数据,也就是说会执行构造函数内的语句*/ #include <iostream>
using namespace std;
class Human
{
public:
Human(){cout << "构造函数执行中……"; i = new int();} //把新开辟的堆的地址赋给Human的成员变量i,同时把999存进去
~Human(){cout << "析构函数执行中……"; delete i;} //如果在对象中新开辟了一个堆,在析构函数中必须有delete i, 否则如果值向该类所在堆的指针被删除之后就找不到i了,从而造成内存泄漏,!!!!!!!!!!!!!!!但是一个在堆中创建的对象通过成员指针在创建新的空间用来保存数据没有什么意义,因为在堆中创建对象的时候已经为  它的所有数据成员提供了保存的空间
int get()const{return *i;}
private:
int *i;
};
int main()
{
Human jack;
cout << jack.get() << endl << endl;
Human *p = new Human;
cout << (*p).get() << endl << endl;
cout << p->get() << endl << endl;//访问堆中对象的两种方法 1:p->get(); 2:(*p).get();
delete p;
/*我们要删除在堆中创建的对象,我们可以直接删除指向该对象的指针,这样会自动调用对象的析构函数来销毁该对象,同时释放内存,在堆中创建的对象不用的时候记得删除,也就是delete p*/
return ;
}

对象在栈中有系统自动回收,对象在堆中由程序员手动释放,否则的话该对象占用的内存等到程序结束的时候才会被系统回收;

栈是一块连续的内存区域,它的大小是2M,也可能是1M,在不同的平台上它的大小不同
内存分配不同:
堆是不连续的内存区域,各块区域由链表将他们串联起来,这些串联起来的内存空间叫做堆
堆的上限是由系统中的有效虚拟内存来定的,因此获得的空间比较大,而且获得空间的方式也比较灵活
执行效率不同:
栈是由系统自动分配,因而执行效率较快,但是程序员不能对其进行操作
堆是由程序员分配的内存,一般速度比较慢,而且容易产生内存碎片,不过使用起来很方便

堆和栈各有优缺点,因此好多时候我们是将堆和栈结合使用的,比如我们在存储一些较大数据的时候,
我们将数据存放在堆中,却将指向该数据的指针存放在栈中,这样可以有效的提高程序的执行速度,
避免一些不该有的碎片,不过一般来说,假如不是特别大的数据,我们一般使用栈,比如函数调用过程中的参数,
返回地址,和局部变量都存放在栈中,这样可以大大加快程序的运行速度

堆中的数据,假设程序员不手动将其释放,它就会一直存放在堆中,程序结束时自动释放
栈中的数据只在函数内有效,超出函数就消失了,
全局变量只有在函数结束时候才会被释放,而且很容易被修改

堆中的每个内存单元都是匿名的,因此你必须在堆中申请一个内存单元地址,然后把它保存在一个指针中,
这样你只有使用该指针才能访问该内存单元的数据

在c++中使用关键字new来创建一个堆并分配内存,在new后面跟一个要分配的内存类型,
编译器根据这个类型来分配内存,比如int *p; p = new int;

由于计算机的内存地址是有限的,因此可能出现没有足够内存而无法满足new的请求,在这种情况下new会返回0
该值被赋给指针之后,该指针就是一个空指针,空指针不会指向任何有效数据,new除了返回空值之外,还会引发异常,
这时候需要进行异常情况处理,

下面代码演示如何创建一个堆并在不使用的时候释放堆中内存空间

/*假如你不需要一段内存空间,那就必须对指向他的指针关键字使用delete
当用delete释放一个指针指向的空间的时候可以将该指针清零,可以避免出错*/
#include <iostream> //qualify翻译为有资格,限制,取得资格
using namespace std;
int main()
{
int *p = new int;
delete p; //这将释放指针所指向的内存,而不会释放指针,因此你还可以使用该指针
p = ;
p = new int;
*p = ;
cout << *p << endl;
delete p;
return ;
}

c++中的 堆和栈的更多相关文章

  1. (十一)C语言中内存堆和栈的区别

    在计算机领域,堆栈是一个不容忽视的概念,我们编写的C语言程序基本上都要用到.但对于很多的初学着来说,堆栈是一个很模糊的概念. 堆栈:一种数据结构.一个在程序运行时用于存放的地方,这可能是很多初学者的认 ...

  2. C语言中的堆与栈20160604

    首先声明这里说的是C语言中的堆与栈,并不是数据结构中的!一.前言介绍:C语言程序经过编译连接后形成编译.连接后形成的二进制映像文件是静态区域由代码段和数据段(由二部分部分组成:只读数据 段,未初始化数 ...

  3. Java中的堆和栈的区别

    当一个人开始学习Java或者其他编程语言的时候,会接触到堆和栈,由于一开始没有明确清晰的说明解释,很多人会产生很多疑问,什么是堆,什么是栈,堆和栈有什么区别?更糟糕的是,Java中存在栈这样一个后进先 ...

  4. java中的堆、栈、常量池

    java中的堆.栈.常量池 分类: java2010-01-15 03:03 4248人阅读 评论(5) 收藏 举报 javastring编译器jvm存储equals Java内存分配: 1. 寄存器 ...

  5. (转)认识java中的堆和栈

    栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆.      Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new. ...

  6. java中的堆与栈

    Java 中的堆和栈 Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配 . 当在一段代码块定义一个变量时,Java就在栈中 ...

  7. 详细介绍Java中的堆、栈和常量池

    下面主要介绍JAVA中的堆.栈和常量池: 1.寄存器 最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈 存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在 ...

  8. Java中的堆和栈

    Java中的堆和栈 栈内存 存放基本数据类型和引用变量 堆内存 存放运行时创建的对象 一般来说,通过new关键字创建出来的对象都放在堆内存中 由于JVM是基于堆栈的虚拟机,而每个Java程序都运行在一 ...

  9. 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型

    小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...

  10. 在JS中关于堆与栈的认识function abc(a){ a=100; } function abc2(arr){ arr[0]=0; }

    平常我们的印象中堆与栈就是两种数据结构,栈就是先进后出:堆就是先进先出.下面我就常见的例子做分析: main.cpp int a = 0; 全局初始化区 char *p1; 全局未初始化区 main( ...

随机推荐

  1. Android应用开发实例篇(1)-----简易涂鸦板

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/03/2378328.html 一.概述 这次要做一个简单的涂鸦板应用,以前在Qt上实现过,突然想 ...

  2. BestCoder Round #47

    1001 Senior's Array 题目链接:1001 题意:给你一个长度为n的序列,你必须修改序列中的某个数为P,求修改后的最大连续子序列和. 思路:数据量比较小,可以直接暴力做, 枚举序列的每 ...

  3. maven build脚本笔记

    如果 code 只存在src/java/main 路径下,直接install就好,不必写<build> 资源文件:edu-common-config <build> <f ...

  4. linux用户管理最常用的三个文件说明(不完整版)

    涉及到三个文本文件:/etc/passwd /etc/shadow /etc/group 文件相关: /etc/passwd和用户名相关 /etc/shadow和密码相关 /etc/group和用户所 ...

  5. [转]swift 学习资源 大集合

    今天看到了一个swift的学习网站,里面收集了很多学习资源 [转自http://blog.csdn.net/sqc3375177/article/details/29206779] Swift 介绍 ...

  6. JS 原型 & 继承

    理解原型链 先看看http://www.ituring.com.cn/article/56184和http://www.cavabiao.com/prototype-and-inherit-of-ja ...

  7. Protel中放置汉字工具的使用图示

    首先先到网上下载Protel中放置汉字工具ProtelHz.然后把ProtelHz中的文件全部解压到Protel99se安装目录X:\Program Files\Design Explorer 99 ...

  8. [Windows编程] #pragma once 和#ifndef ... #define ... #endif 比较

    C++中防止头文件被多次include 的常见方式有: 1) 用#ifndef ...  #define ... #endif  宏 #ifndef __MYHEADER_H__#define __M ...

  9. Oracle DBA常用的系统表

    1.2 DBA常用的表1.2.1  dba_开头    dba_users数据库用户信息    dba_segments  表段信息    dba_extents    数据区信息    dba_ob ...

  10. How to setup linked servers for SQL Server and Oracle 64 bit client

    感谢作者:Tim Ford. 图文并茂. 原帖地址: http://www.mssqltips.com/sqlservertip/1433/how-to-setup-linked-servers-fo ...