c++中的 堆和栈

/*用指针p存储堆中的空间时,在将第二块内存空间赋给p之前,我们要释放p原来指向的内存空间,
这样才不会造成内存泄漏,不然的话p原来记录的内存空间就找不到了,而且也无法再次利用
注意:你在使用new以后,加入不再使用该块内存空间,那么一定要用delete来释放它*/

/*堆中可以保存变量,也可以保存对象,我们可以将对象保存在堆中,通过指针来访问它 */

/*创建对象的时候会自动调用类的构造函数来初始化对象的成员数据,也就是说会执行构造函数内的语句*/

#include <iostream>
using namespace std;
class Human
{
public:
    Human(){cout << "构造函数执行中……"; i = new int(999);} //把新开辟的堆的地址赋给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 0;
}

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

栈是一块连续的内存区域,它的大小是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 = 0;
    p = new int;
    *p = 8;
    cout << *p << endl;
    delete p;
    return 0;
}
 
时间: 2024-10-21 05:12:37

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

C语言中的堆与栈20160604

首先声明这里说的是C语言中的堆与栈,并不是数据结构中的!一.前言介绍:C语言程序经过编译连接后形成编译.连接后形成的二进制映像文件由栈,堆,数据段(由三部分部分组成:只读数据 段,已经初始化读写数据段,未初始化数据段即BBS)和代码段组成,如下图所示: 其中所谓静态,就是一定会存在的而且会永恒存在.不会消失,这样的数据包括常量.常变量(const 变量).静态变 量.全局变量等. 动态的话,就是会变化的了.动态的区域,就是堆和栈.这个栈应该称作 call stack,上面会存放函数的返回地址.

C,C++中的堆与栈

堆栈是一种执行“后进先出”算法的数据结构. 设想有一个直径不大.一端开口一端封闭的竹筒.有若干个写有编号的小球,小球的直径比竹筒的直径略小.现在把不同编号的小球放到竹筒里面,可以发现一种规律:先放进去的小球只能后拿出来,反之,后放进去的小球能够先拿出来.所以“先进后出”就是这种结构的特点. 堆栈就是这样一种数据结构.它是在内存中开辟一个存储区域,数据一个一个顺序地存入(也就是“压入——push”)这个区域之中.有一个地址指针总指向最后一个压入堆栈的数据所在的数据单元,存放这个地址指针的寄存器就叫

java中的堆和栈

Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用. 堆内存用于存放由new创建的对象和数组以及包装类.在堆中分配的内存,由java虚拟机自动垃圾回收器来管理.在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象

Java中的堆和栈的区别

当一个人开始学习Java或者其他编程语言的时候,会接触到堆和栈,由于一开始没有明确清晰的说明解释,很多人会产生很多疑问,什么是堆,什么是栈,堆和栈有什么区别?更糟糕的是,Java中存在栈这样一个后进先出(Last In First Out)的顺序的数据结构,这就是java.util.Stack.这种情况下,不免让很多人更加费解前面的问题.事实上,堆和栈都是内存中的一部分,有着不同的作用,而且一个程序需要在这片区域上分配内存.众所周知,所有的Java程序都运行在JVM虚拟机内部,我们这里介绍的自然

java中的堆、栈、常量池

java中的堆.栈.常量池 分类: java2010-01-15 03:03 4248人阅读 评论(5) 收藏 举报 javastring编译器jvm存储equals Java内存分配: 1. 寄存器:我们在程序中无法控制2. 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中3. 堆:存放用new产生的数据4. 静态域:存放在对象中用static定义的静态成员5. 常量池:存放常量6. 非RAM(随机存取存储器)存储:硬盘等永久存储空间-----------------

Jvm(29),理解升级----C语言中的堆和栈的区别 (可以借鉴)

在计算机领域,堆栈是一个不容忽视的概念,我们编写的C语言程序基本上都要用到.但对于很多的初学着来说,堆栈是一个很模糊的概念. 堆栈:一种数据结构.一个在程序运行时用于存放的地方,这可能是很多初学者的认识,因为我曾经就是这么想的和汇编语言中的堆栈一词混为一谈.我身边的一些编程的朋友以及在网上看帖遇到的朋友中有好多也说不清堆栈,所以我想有必要给大家分享一下我对堆栈的看法,有说的不对的地方请朋友们不吝赐教,这对于大家学习会有很大帮助. 一.数据结构中的栈和堆 首先在数据结构上要知道堆栈,尽管我们这么称

Java中的堆与栈

一.栈 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用.但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性.栈数据可以共享. 那些数据存放在栈中? 基本数据类型(int, short, long, byte, float, double, boolean, char)的变量存放于栈中. 对象的引用存放于栈中. 栈数据共享具体指什么意思? int a = 3; int b = 3

内存分配中的堆、栈、静态区、只读区

内存中的栈区处于相对较高的地址以地址的增长方向为上的话,栈地址是向下增长的,栈中分配局部变量空间,堆区是向上增长的用于分配程序员申请的内存空间.另外还有静态区是分配静态变量,全局变量空间的:只读区是分配常量和程序代码空间的:以及其他一些分区.对于常量,在实际情况中,是会复用的,比如变量a和b都赋值为”abc”则实际上他们指向同一块地址. main.cpp int a = 0; //全局初始化区 char *p1; //全局未初始化区 main() { int b; //栈 char s[] =

详细介绍Java中的堆和栈

栈与堆都是Java用来在RAM中寄存数据的中央.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运转时数据区,类的对象从中分配空间.这些对象经过new.newarray.anewarray和 multianewarray等指令建立,它们不需要程序代码来显式的释放.堆是由垃圾回收来负责的,堆的优势是可以静态地分配内存大小,生活期也不用事 先通知编译器,因为它是在运转时静态分配内存的,Java的垃圾搜集器会自动收走这些不再运用的数据.但缺陷是,由于要在运转时静态