精华内容
下载资源
问答
  • 文章主要介绍了堆和栈区别联系
  • 今天小编就为大家分享一篇关于C++堆和栈区别联系讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
  • C++堆和栈区别联系

    千次阅读 2019-05-03 12:19:47
    1、堆和栈的含义 在C++中,内存分为5个区:堆、占、自由存储区、全局/静态存储区、常量存储区 1、栈: 由系统自动分配和释放内存,存放函数的参数值,局部变量的值等,分配方式类似于数据结构中的栈 。 2、堆: 一般...

    1、堆和栈的含义

    在C++中,内存分为5个区:堆、占、自由存储区、全局/静态存储区、常量存储区
    1、: 由系统自动分配和释放内存,存放函数的参数值,局部变量的值等,分配方式类似于数据结构中的栈 。
    2、: 一般由程序员分配和释放内存(由new申请内存,delete释放内存), 若程序员不释放,会造成内存泄露,程序结束时可能由OS回收,分配方式类似于链表 。
    3、自由存储区: 是由malloc等分配的内存块,和堆十分相似,用free来释放。
    4、全局/静态存储区: 全局变量和静态变量被分配到同一块内存中(在C语言中,全局变量又分为初始化的和未初始化的,C++中没有这一区分)。
    5、常量存储区: 里边存放常量,不允许修改。

    2、堆和栈的区别

    堆和栈的区别
    堆(heap)栈(stack)
    管理方式堆中资源由程序员控制栈资源由编译器自动管理,无需程序员管理
    内存管理机制系统有一个记录空闲内存地址的链表,当系统收到程序申请时,遍历该链表,寻找第一个空间大于申请空间的堆结点,删除空闲结点链表中的该结点,并将该结点空间分配给程序(大多数系统会在这块内存空间首地址记录本次分配的大小,这样delete才能正确释放本内存 空间,另外系统会将多余的部分重新放入空闲链表中)只要栈的剩余空间大于所申请空间,系统为程序提供内存,否则报异常提示栈出
    空间大小堆是不连续的内存区域(因为系统是用链表来存储空闲内存地址,自然不是连续的),堆大小受限于计算机系统中有效的虚拟内存(32bit 系统理论上是4G),所以堆的空间比较灵活,比较大栈是一块连续的内存区域,大小是操作系统预定好的,windows下栈大小是2M(也有是1M,在编译时确定,VS中可设置)
    碎片问题对于堆,频繁的new/delete会造成大量碎片,使程序效率降低对于栈,它是一个先进后出的队列,进出一一对应,不会产生碎片
    生长方向堆向上,向高地址方向增长栈向下,向低地址方向增长
    分配方式动态分配栈有静态分配和动态分配, 静态分配由编译器完成(如局部变量分配),动态分配由alloca函数分配,但栈的动态分配的资源由编译器进行释放,无需程序员实现
    分配效率堆由C/C++函数库提供,机制很复杂。所以堆的效率比栈低很多栈是极其系统提供的数据结构,计算机在底层对栈提供支持,分配专门 寄存 器存放栈地址,栈操作有专门指令

    3、测试比较

    测试程序如下:

    using namespace std;
    
    class Base {
    public:
        void f() { cout << "Base::f" << endl; }
        void g() { cout << "Base::g" << endl; }
        void h() { cout << "Base::h" << endl; }
    };	
    
    int main()
    {
        Base A;
        Base B;
        Base C;
        Base *D = new Base;
        Base E;
        Base *F = new Base;
        Base *G = new Base;;
    
        cout << "一个class Base的大小为:" << sizeof(Base) << endl;
        cout << "一个class Base *D的大小为:" << sizeof(D) << endl;
        cout << "地址A:" << (int*)(&A) << endl;
        cout << "地址B:" << (int*)(&B) << endl;
        cout << "地址C:" << (int*)(&C) << endl;
        cout << "地址D:" << D << endl;
        cout << "地址E:" << (int*)(&E) << endl;
        cout << "地址F:" << F << endl;
        cout << "地址G:" << G << endl;
        
        getchar();
    }
    

    测试结果如下:
    测试结果
    测试结果分析:

    1、对于ABCE,其位于栈上,其地址是向低地址方向生长的,内存连续,每次递减1(Base的大小为1),类似于一个先进后出的队列。

    2、对于DFG,其位于堆上,其地址是向高地址增长的,而且内存是不连续的。

    4、用static来控制变量的储存方式和可见性

    static的内部机制
      静态数据成员要在程序一开始运行时就必须存在。因为函数在程序运行中被调用,所以静态数据成员不能在任何函数内分配空间和初始化。这样,它的空间分配有三个可能的地方,一是作为类的外部接口的头文件,这里有类声明;二是类定义的内部实现,这里有类的成员函数定义;三是应用程序的 main()函数前的全局数据声明和定义处
      static 被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间,静态数据成员按定义出现的先后顺序依次初始化,注意静态成员嵌套时,要保证所嵌套的成员已经初始化了,消除时的顺序是初始化的反顺序
    static的优势
      可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的 值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。引用静态数据成员时,采用如下格式:
    <类名>::<静态成员名>

    其他:
    (1) 类的静态成员函数是属于整个类而非类的对象,所以它没有this指针,这就导致了它仅能访问类的静态数据和静态成员函数。
    (2) 不能将静态成员函数定义为虚函数。
    (3) 由于静态成员声明于类中,操作于其外,所以对其取地址操作,就多少有些特殊,变量地址是指向其数据类型的指针,函数地址类型是一个“nonmember 函数指针”。
    (4) 由于静态成员函数没有 this 指针,所以就差不多等同于 nonmember 函数,结果就产生了一个意想不到的好处:成为一个 callback 函数,使得我们得以将 c++ 和 c-based x window 系统结合,同时也成功的应用于线程函数身上。
    (5) static 并没有增加程序的时空开销,相反她还缩短了子类对父类静态成员的访问时间,节省了子类的内存空间。
    (6) 静态数据成员在<定义或说明>时前面加关键字 static。
    (7) 静态数据成员是静态存储的,所以必须对它进行初始化。
    (8) 静态成员初始化与一般数据成员初始化不同:

    • 初始化在类的外部进行,而前面不加 static,以免与一般静态变量或对象相混淆;
    • 初始化时不加该成员的访问权限控制符private、public;
    • 初始化时使用作用域运算符来标明它所属类;
    展开全文
  • 1、申请方式 ...(heap)需要程序员自己申请,并指明大小。 例如,在C语言中的malloc函数: char *p = NULL; p = (char *)malloc(10); 在C++中的new运算符 p = new char[10]; 2、申请后的系...

    1、申请方式

    栈(stack)由系统自动分配。

    例如,在函数中声明一个局部变量:

    int b;

    系统会自动在栈中为b开辟内存空间。

    堆(heap)需要程序员自己申请,并指明大小。

    例如,在C语言中的malloc函数:

    char *p = NULL;
    p = (char *)malloc(10);

    在C++中的new运算符

    p = new char[10];

    2、申请后的系统响应

        :只要栈的剩余空间大于所申请的空间,系统为程序提供内存,否则将报异常,提示栈溢出。因此效率较高,但程序员无法控制。

        :当系统收到程序的申请时,会先遍历操作系统中的一个记录空闲内存地址的链表,寻找第一个空间大于所申请空间的堆节点,然后将该节点从空闲节点链表中删除,并将该节点的空间分配给程序。另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样对应的释放接口(如free或delete)才能正确地释放本内存空间。因此效率较低,而且容易产生内存碎片,但是使用方便。

    3、申请大小的限制

        :在windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域。如在windows下栈的大小为2M。如果申请的空间大于栈的剩余空间将提示overflow。因此,从栈获得的空间较小。

        :堆是向高地址扩展的数据结构,是不连续的内存区域。堆的大小受限于计算机中有效的虚拟内存。因此,从堆获得的空间比较大,也比较灵活。

    ------------------------------------------------The end---------------------------------------------------

    展开全文
  • 堆和栈区别以及联系

    千次阅读 2020-07-16 19:17:59
    区别有:内存存储的是局部变量而内存是实体,内存的更新速度高于内存,内存的生命周期一结束就会被释放而内存会被垃圾回收机制不定时回收 中存放的是对象的引用及对象方法中的局部变量的值...

    堆与栈的区别有:栈内存存储的是局部变量而堆内存是实体,栈内存的更新速度高于堆内存,栈内存的生命周期一结束就会被释放而堆内存会被垃圾回收机制不定时回收

    栈中存放的是对象的引用及对象方法中的局部变量的值(参数的值)
    堆中存放的是实例对象及成员变量的值(属性的值)
    方法区存放类的方法代码,变量名,方法名,访问权限,返回值等等
    在这里插入图片描述
    局部变量,如果是基本数据类型,那么就直接存在栈中,如果是引用数据类型(类、接口、数组),比如String str = new String(“12”);,会把对象存在堆中,对象的引用(指针)存在栈中,

    成员变量,类的成员在不同对象中各不相同(属性和方法),基本数据类型和引用数据类型都存储在这个对象中,作为一个整体存储在堆中。而类的方法是所有的对象共享的,方法是存在方法区的,只用当调用的时候才会被压栈,不用的时候是占内存的。

    成员变量和局部变量的区别
    (1)在类中的位置不同
    成员变量:类中方法外
    局部变量:方法定义中或者方法声明上
    (2)在内存中的位置不同
    成员变量:在堆中
    局部变量:在栈中
    (3)生命周期不同
    成员变量:随着对象的创建而存在,随着对象的消失而消失
    局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
    (4)初始化值不同
    成员变量:有默认值
    局部变量:没有默认值,必须定义,赋值,然后才能使用

    局部变量基本上是方法的参数。

    在说堆和栈之前,我们需要了解JVM(虚拟机)中内存的划分:

    任何软件在运行时都需要空间,Java虚拟机也不例外。JVM运行时在内存中会开辟一片内存区域,启动时在自己的内存区域中进行更细致的划分,因为虚拟机中每一片内存处理的方式都不同,所以要单独进行管理。JVM内存的划分有五部分分别是:

    寄存器

    本地方法区

    方法区

    栈内存

    堆内存

    今天将要介绍的是栈内存与堆内存的区别

    栈内存

    栈内存首先是一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量(方法外的是全局变量),for循环内部定义的也是局部变量,是先加载函数才能进行局部变量的定义,所以方法先进栈,然后再定义变量,变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。

    堆内存

    存储的是数组和对象(其实数组就是对象),凡是new建立的都是在堆中,堆中存放的都是实体(对象),实体用于封装数据,而且是封装多个(实体的多个属性),如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但是栈不一样,栈里存放的都是单个变量,变量被释放了,那就没有了。堆里的实体虽然不会被释放,但是会被当成垃圾,Java有垃圾回收机制不定时的收取。

    下面将通过具体的图例来详细讲解一下堆和栈

    比如说主函数中的语句

    1

    int [] arr=new int [3];
    

    主函数先进栈,在栈中定义一个变量arr,接下来为arr赋值,但是右边不是一个具体值,是一个实体。实体创建在堆里,在堆里首先通过new关键字开辟一个空间,内存在存储数据的时候都是通过地址来体现的,地址是一块连续的二进制,然后给这个实体分配一个内存地址。数组都是有一个索引,数组这个实体在堆内存中产生之后每一个空间都会进行默认的初始化(这是堆内存的特点,未初始化的数据是不能用的,但在堆里是可以用的,因为初始化过了,但是在栈里没有),不同的类型初始化的值不一样。所以堆和栈里就创建了变量和实体

    在这里插入图片描述

    堆和栈的联系

    上例中给堆分配了一个地址,然后把堆的地址赋给arr,arr就通过地址指向了数组。所以arr想操纵数组时,就通过地址,而不是直接把实体都赋给它。这种我们不称为基本数据类型,而叫引用数据类型。称为arr引用了堆内存当中的实体。
    在这里插入图片描述

    如果当int [] arr=null;且arr不做任何指向,null的作用就是取消引用数据类型的指向。

    当一个实体,没有引用数据类型指向的时候,它在堆内存中不会被释放,而被当做一个垃圾,在不定时的时间内自动回收,因为Java有一个自动回收机制。自动回收机制(程序)自动监测堆里是否有垃圾,如果有,就会自动的做垃圾回收的动作,但是什么时候收不一定。

    堆与栈的区别

    1.栈内存存储的是局部变量而堆内存存储的是实体;

    2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;

    3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不


    本文著作权归作者所有。
    商业转载请联系作者获得授权,非商业转载请注明出处。
    来源地址:https://www.php.cn/faq/416802.html
    来源:php中文网(www.php.cn)
    © 版权声明:转载请附上原文链接!

    展开全文
  • 堆和栈的概念和区别

    万次阅读 多人点赞 2017-04-27 19:06:37
    在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分:  Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片内存区域,启动时...

          在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分:

          Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片内存区域,启动时在自己的内存区域中进行更细致的划分,因为虚拟机中每一片内存处理的方式都不同,所以要单独进行管理。

          JVM内存的划分有五片:

           1.   寄存器;

           2.   本地方法区;

           3.   方法区;

           4.   栈内存;

           5.   堆内存。

           我们重点来说一下堆和栈:

           栈内存:栈内存首先是一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量(方法外的是全局变量),for循环内部定义的也是局部变量,是先加载函数才能进行局部变量的定义,所以方法先进栈,然后再定义变量,变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。

           堆内存:存储的是数组和对象(其实数组就是对象),凡是new建立的都是在堆中,堆中存放的都是实体(对象),实体用于封装数据,而且是封装多个(实体的多个属性),如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但是栈不一样,栈里存放的都是单个变量,变量被释放了,那就没有了。堆里的实体虽然不会被释放,但是会被当成垃圾,Java有垃圾回收机制不定时的收取。

          下面我们通过一个图例详细讲一下堆和栈:

          比如主函数里的语句   int [] arr=new int [3];在内存中是怎么被定义的:

          主函数先进栈,在栈中定义一个变量arr,接下来为arr赋值,但是右边不是一个具体值,是一个实体。实体创建在堆里,在堆里首先通过new关键字开辟一个空间,内存在存储数据的时候都是通过地址来体现的,地址是一块连续的二进制,然后给这个实体分配一个内存地址。数组都是有一个索引,数组这个实体在堆内存中产生之后每一个空间都会进行默认的初始化(这是堆内存的特点,未初始化的数据是不能用的,但在堆里是可以用的,因为初始化过了,但是在栈里没有),不同的类型初始化的值不一样。所以堆和栈里就创建了变量和实体:

                                                     

         那么堆和栈是怎么联系起来的呢?

         我们刚刚说过给堆分配了一个地址,把堆的地址赋给arr,arr就通过地址指向了数组。所以arr想操纵数组时,就通过地址,而不是直接把实体都赋给它。这种我们不再叫他基本数据类型,而叫引用数据类型。称为arr引用了堆内存当中的实体。(可以理解为c或c++的指针,Java成长自c++和c++很像,优化了c++)                                                               

         

                  如果当int [] arr=null;

                  arr不做任何指向,null的作用就是取消引用数据类型的指向。

                  当一个实体,没有引用数据类型指向的时候,它在堆内存中不会被释放,而被当做一个垃圾,在不定时的时间内自动回收,因为Java有一个自动回收机制,(而c++没有,需要程序员手动回收,如果不回收就越堆越多,直到撑满内存溢出,所以Java在内存管理上优于c++)。自动回收机制(程序)自动监测堆里是否有垃圾,如果有,就会自动的做垃圾回收的动作,但是什么时候收不一定。

                 所以堆与栈的区别很明显:

                1.栈内存存储的是局部变量而堆内存存储的是实体;

                2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;

                3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。



    展开全文
  • 堆和栈区别联系,从C语言的角度解释堆和栈的主要区别
  • JavaScript 中堆和栈区别

    千次阅读 2020-12-02 23:24:48
    JS变量都存放在内存中,而内存给变量开辟了两块区域,分别为区域和堆区域 像个容器,容量小速度快 像个房间,容量较大 讲这些之前我们先说说基本数据类型引用数据类型 我们知道在js中的数据类型可以分为...
  • 内存中堆和栈区别

    万次阅读 多人点赞 2019-02-19 16:39:41
    在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分: Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片内存区域,启动时在...
  • Java堆和栈区别/联系详解

    千次阅读 2017-12-18 13:48:59
    Java堆和栈区别/联系详解关于Java中堆栈内存的知识,算是基础知识,和C语言中的指针有一些类似,面试中也经常会被问到,特别是跟Java和C都有关的开发工作。一.堆栈的联系在Java中,内存分为两种,一种是栈内存,另...
  • 堆和栈区别-JVM内存

    千次阅读 2017-06-13 11:28:47
    JAVA JVM的内存的堆和栈分别用途是什么呢? 先了解一JVM的内存分布,大体见下图所示:
  • Java面试--堆和栈的概念和区别

    万次阅读 多人点赞 2018-09-19 20:30:33
    堆和栈的概念和区别【转载自博客】 在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分:  Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行...
  • C++的内存分配可以分为3种,静态内存、内存、内存。 一、静态内存:存储静态变量全局变量 1、静态变量(包括局部静态变量、类的静态数据成员、全局静态变量)在静态内存中分配内存,当整个程序运行完毕之后才...
  • Linux_堆和栈区别

    2019-07-19 18:16:56
    堆栈的区别要从虚拟地址空间说起,在虚拟地址空间的布局中,有(.text)段、(.data)段、(.bss)段、、命令行参数、环境变量等,如图所示 从图中可以看出,堆栈是俩快完全不不同的内存。 内存是由操作系统分配...
  • JS中堆和栈区别

    千次阅读 2018-08-06 21:14:24
    JS中的堆和栈是一种十分抽象的概念,事实上是不存在的。栈指的是本身存在的内容,存储在本地的内容。而堆指的是在本地放不下的内容,这个时候就由堆中的地址来寻找这些内容。...
  • c#中堆和栈区别

    2017-09-15 15:14:21
    **这篇文章属于转载,但是我实在找不到原作者是谁,所以无法附上原文链接。...:全称是托管,英文Heap解释1、是编译期间就分配好的内存空间,因此你的代码中必须就的大小有明确的定义; 是程序运行
  • (heap)和栈(stack)的区别 1、存储 栈:变量、对象的引用 :实例对象 2、速度 栈:存取速度快 :存取速度慢 3、线程访问 栈:每个线程都有一个栈区 :所有线程共享一个区 4、垃圾回收 栈:比较频繁 ...
  • 堆和栈区别可以用如下的比喻来看出: 使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走 不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作 他的好处是快捷,但是自由度小 ...
  • 堆和栈区别

    2013-09-19 15:07:22
    堆和栈区别 给初学者 详细讲诉了C语言中堆与栈的区别联系
  • JAVA中堆和栈区别联系

    千次阅读 2019-04-25 14:01:14
    一、Java的内存和栈内存 Java把内存划分成两种:一种是内存,一种是栈内存。 :主要用于储存实例化的对象,数组。由JVM动态分配内存空间。一个JVM只有一个内存,线程是可以共享数据的。 栈:主要用于储存...
  • 是一块动态内存,是先进后出的的一种方法,队列是一种先进先出的线性表 0.利用redis的list数据类型构造栈和队列: List类型 常用命令: lpush(从list最左边加入元素)、lpop(从list最左边取出元素)、 rpush...
  • 在java语言中,都是内存中存放数据的地方,变量分为基本数据类型引用类型,基本数据类型的变量(列如,int,short,long,byte,float,double,boolean以及char等)以及对象的引用变量,其内存都分配在上,...
  • 堆和栈区别(面试经验总结)

    千次阅读 2018-10-01 11:52:17
    C++中,内存分为5个区:、自由存储区、全局/静态存储区常量存储区。 :是由编译器在需要时自动分配,不需要时自动清除的变量存储区。通常存放局部变量、函数参数等。 :是由new分配的内存块,由...
  • 1.联系:引用对象、数组时,里定义变量保存中目标的首地址 2.区别: 2.1管理方式:自动释放(编译器自动执行的操作),需要GC 2.2空间大小:小 2.3碎片相关:产生的碎片远小于 2.4分配方式:...
  • linux程序设计:堆和栈区别

    千次阅读 2016-09-26 10:32:44
     1、区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其  操作方式类似于数据结构中的。  2、区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回 ...
  • 堆和栈的概念和区别 在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分: Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片...
  • 区别 :队列优先,先进先出(FIFO—firstinfirstout)。 ,先进后出(FILO—First-In/Last-Out)。 一般情况下,如果有人把堆栈合起来说,那它的意思是,可不是(数据结构):可以被看成是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 31,957
精华内容 12,782
关键字:

堆和栈的区别和联系