精华内容
下载资源
问答
  • C++ primer plus中提到通过new创建对象,是驻留区,如图所示,但new分配内存不是在堆区的吗,求解!![图片](https://img-ask.csdn.net/upload/201705/11/1494471443_946485.jpg)
  • new创建对象对象保存在堆还是栈? –>内存是用来存放由new创建的对象和数组,即动态申请的内存都存放在堆内存 –>内存是用来存放函数中定义的一些基本类型的变量和对象的引用变量 例子:局部变量存放...

    new创建对象,对象保存在堆还是栈?

    –>堆内存是用来存放由new创建的对象和数组,即动态申请的内存都存放在堆内存

    –>栈内存是用来存放在函数中定义的一些基本类型的变量和对象的引用变量

    例子:局部变量存放在栈;new函数和malloc函数申请的内存在堆;函数调用参数,函数返回值,函数返回地址存放在栈

    堆和栈的区别

    1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其
    操作方式类似于数据结构中的栈。
    2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回
    收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表 ,呵呵。

    使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就
    走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自
    由度小。
    使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由
    度大。
    ————————————————
    版权声明:本文为CSDN博主「WX_Chen」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/kl1411/article/details/65959992

    展开全文
  • 成员变量在栈还是堆上?

    千次阅读 2016-08-22 15:53:32
    class CTest { public: int iCount; };iCount在栈还是堆上取决于类对象的声明方式;如果是: CTest = new CTest(); 那么iCount在堆上;如果是: CTest cTest; 那么iCount在栈上;

    class CTest
    {
    public:
    int iCount;
    };

    iCount在栈上还是堆上取决于类对象的声明方式;

    如果是:
    CTest = new CTest();
    那么iCount在堆上;

    如果是:
    CTest cTest;
    那么iCount在栈上;

    展开全文
  • 吃人的那些 Java 名词:对象、引用、

    万次阅读 多人点赞 2019-09-05 15:57:09
    作为一个有着 8 年 Java 编程经验的 IT 老兵,说起来很惭愧,我被 Java 当中的四五个名词一直困扰着:**对象、引用、、堆栈**(可同堆栈,因此是四个名词,也是五个名词)。每次我看到这几个名词,都隐隐...

    作为一个有着 8 年 Java 编程经验的 IT 老兵,说起来很惭愧,我被 Java 当中的四五个名词一直困扰着:对象、引用、堆、栈、堆栈(栈可同堆栈,因此是四个名词,也是五个名词)。每次我看到这几个名词,都隐隐约约觉得自己在被一只无形的大口慢慢地吞噬,只剩下满地的衣服碎屑(为什么不是骨头,因为骨头也好吃)。

    记得中学的课本上,有一篇名为《狂人日记》课文;那时候根本理解不了鲁迅写这篇文章要表达的中心思想,只觉得满篇的“吃人”令人心情压抑;老师在讲台上慷慨激昂的讲,大多数的同学同我一样,在课本面前“痴痴”的发呆。

    十几年后,再读《狂人日记》,恍然如梦:

    鲁迅先生以狂人的口吻,再现了动乱时期下中国人的精神状态,视角新颖,文笔细腻又不乏辛辣之味。

    当时的中国,混乱成了主色调。以清廷和孔教为主的封建旧思想还在潜移默化地影响着人们的思想,与此同时以革命和新思潮为主的现代思想已经开始了对大众灵魂的洗涤和冲击。

    最近,和沉默王二技术交流群(120926808)的群友们交流后,Java 中那四五个会吃人的名词:对象、引用、堆、栈、堆栈,似乎在脑海中也清晰了起来,尽管疑惑有时候仍然会在阴云密布时跑出来——正鉴于此,这篇文章恰好做一下归纳。

    一、对象和引用

    在 Java 中,尽管一切都可以看做是对象,但计算机操作的并非对象本身,而是对象的引用。 这话乍眼一看,似懂非懂。究竟什么是对象,什么又是引用呢?

    先来看对象的定义:按照通俗的说法,每个对象都是某个类(class)的一个实例(instance)。那么,实例化的过程怎么描述呢?来看代码(类是 String):

    new String("我是对象张三");
    new String("我是对象李四");
    

    在 Java 中,实例化指的就是通过关键字“new”来创建对象的过程。以上代码在运行时就会创建两个对象——“我是对象张三"和"我是对象李四”;现在,该怎么操作他们呢?

    去过公园的同学应该会见过几个大爷,他们很有一番本领——个个都能把风筝飞得老高老高,徒留我们眼馋的份!风筝飞那么高,没办法直接用手拽着飞啊,全要靠一根长长的看不见的结实的绳子来牵引!操作 Java 对象也是这个理,得有一根绳——也就是接下来要介绍的“引用”(我们肉眼也常常看不见它)。

    String zhangsan, lisi;
    zhangsan = new String("我是对象张三");
    lisi = new String("我是对象李四");
    

    这三行代码该怎么理解呢?

    先来看第一行代码:String zhangsan, lisi;——声明了两个变量 zhangsan 和 lisi,他们的类型为 String。

    ①、歧义:zhangsan 和 lisi 此时被称为引用。

    你也许听过这样一句古文:“神之于形,犹利之于刀;未闻刀没而利存,岂容形亡而神在?”这是无神论者范缜(zhen)的名言,大致的意思就是:灵魂对于肉体来说,就像刀刃对于刀身;从没听说过刀身都没了刀刃还存在,那么怎么可能允许肉体死亡了而灵魂还在呢?

    “引用”之于对象,就好比刀刃之于刀身,对象还没有创建,又怎么存在对象的“引用”呢?

    如果 zhangsan 和 lisi 此时不能被称为“引用”,那么他们是什么呢?答案很简单,就是变量啊!(鄙人理解)

    ②、误解:zhangsan 和 lisi 此时的默认值为 null

    应该说 zhangsan 和 lisi 此时的值为 undefined——借用 JavaScript 的关键字;也就是未定义;或者应该是一个新的关键字 uninitialized——未初始化。但不管是 undefined 还是 uninitialized,都与 null 不同。

    既然没有初始化,zhangsan 和 lisi 此时就不能被使用。假如强行使用的话,编译器就会报错,提醒 zhangsan 和 lisi 还没有出生(初始化);见下图。

    如果把 zhangsan 和 lisi 初始化为 null,编译器是认可的(见下图);由此可见,zhangsan 和 lisi 此时的默认值不为 null

    再来看第二行代码:zhangsan = new String("我是对象张三");——创建“我是对象张三"的 String 类对象,并将其赋值给 zhangsan 这个变量。

    此时,zhangsan 就是"我是对象张三"的引用;“=”操作符赋予了 zhangsan 这样神圣的权利。

    第三行代码 lisi = new String("我是对象李四");和第二行代码 zhangsan = new String("我是对象张三");同理。

    现在,我可以下这样一个结论了——对象是通过 new 关键字创建的;引用是依赖于对象的;= 操作符把对象赋值给了引用

    我们再来看这样一段代码:

    String zhangsan, lisi;
    zhangsan = new String("我是对象张三");
    lisi = new String("我是对象李四");
    zhangsan = lisi;
    

    zhangsan = lisi; 执行过后,zhangsan 就不再是"我是对象张三"的引用了;zhangsan 和 lisi 指向了同一个对象(“我是对象李四”);因此,你知道 System.out.println(zhangsan == lisi); 打印的是 false 还是 true 了吗?

    二、堆、栈、堆栈

    谁来告诉我,为什么有很多地方(书、博客等等)把栈叫做堆栈,把堆栈叫做栈?搞得我都头晕目眩了——绕着门柱估计转了 80 圈,不晕才怪!

    我查了一下金山词霸,结果如下:

    我的天呐,更晕了,有没有!怎么才能不晕呢?我这里有几招武功秘籍,你们尽管拿去一睹为快:

    1)以后再看到堆、栈、堆栈三个在一起打牌的时候,直接把“堆栈”踢出去;这仨人不适合在一起玩,因为堆和栈才是老相好;你“堆栈”来这插一脚算怎么回事;这世界上只存在“堆、栈”或者“堆栈”(标点符号很重要哦)。

    2)堆是在程序运行时在内存中申请的空间(可理解为动态的过程);切记,不是在编译时;因此,Java 中的对象就放在这里,这样做的好处就是:

    当需要一个对象时,只需要通过 new 关键字写一行代码即可,当执行这行代码时,会自动在内存的“堆”区分配空间——这样就很灵活。

    另外,需要记住,堆遵循“先进后出”的规则(此处有雷)。就好像,一个和尚去挑了一担水,然后把一担水装缸里面,等到他口渴的时候他再用瓢舀出来喝。请放肆地打开你的脑洞脑补一下这个流程:缸底的水是先进去的,但后出来的。所以,我建议这位和尚在缸上贴个标签——保质期 90 天,过期饮用,后果自负!

    还是记不住,看下图:

    (不好意思,这是鼎,不是缸,将就一下哈)

    3)栈,又名堆栈(简直了,完全不符合程序员的思维啊,我们程序员习惯说一就是一,说二就是二嘛),能够和处理器(CPU,也就是脑子)直接关联,因此访问速度更快;举个十分不恰当的例子哈——眼睛相对嘴巴是离脑子近的一方,因此,你可以一目十行,但绝对做不到一开口就读十行字,哪怕十个字也做不到

    既然访问速度快,要好好利用啊!Java 就把对象的引用放在栈里。为什么呢?因为引用的使用频率高吗?

    不是的,因为 Java 在编译程序时,必须明确的知道存储在栈里的东西的生命周期,否则就没法释放旧的内存来开辟新的内存空间存放引用——空间就那么大,前浪要把后浪拍死在沙滩上啊。

    现在清楚堆、栈和堆栈了吧?

    三、基本数据类型

    先来看《Java 编程思想》中的一段话:

    在程序设计中经常用到一系列类型,他们需要特殊对待。之所以特殊对待,是因为 new 将对象存储于“堆”中,故用 new 创建一个对象──特别小、简单的变量,往往不是很有效。因此,不用new来创建这类变量,而是创建一个并非是引用的变量,这个变量直接存储值,并置于栈中,因此更加高效。

    在 Java 中,这些基本类型有:boolean、char、byte、short、int、long、float、double 和 void;还有与之对应的包装器:Boolean、Character、Byte、Short、Integer、Long、Float、Double 和 Void;它们之间涉及到装箱和拆箱,点击链接。

    看两行简单的代码:

     int a = 3;
     int b = 3;
    

    这两行代码在编译的时候是什么样子呢?

    编译器当然是先处理 int a = 3;,不然还能跳过吗?编译器在处理 int a = 3; 时在栈中创建了一个变量为 a 的内存空间,然后查找有没有字面值为 3 的地址,没找到,就开辟一个存放 3 这个字面值的地址,然后将 a 指向 3 的地址。

    编译器忙完了 int a = 3;,就来接着处理 int b = 3;;在创建完 b 的变量后,由于栈中已经有 3 这个字面值,就将 b 直接指向 3 的地址;就不需要再开辟新的空间了。

    依据上面的概述,我们假设在定义完 a 与 b 的值后,再令 a=4,此时 b 是等于 3 呢,还是 4 呢?

    思考一下,再看答案哈。

    答案揭晓:当编译器遇到 a = 4;时,它会重新搜索栈中是否有 4 的字面值,如果没有,重新开辟地址存放 4 的值;如果已经有了,则直接将 a 指向 4 这个地址;因此 a 值的改变不会影响到 b 的值哦。

    最后,留个作业吧,下面这段代码在运行时会输出什么呢?

    public class Test1 {
        public static void main(String args[]) {
            int a = 1;
            int b = 1;
    
            a = 2;
    
            System.out.println(a);
            System.out.println(b);
    
            TT t = new TT("T");
            TT t1 = t;
            t.setName("TT");
    
    
            System.out.println(t.getName());
            System.out.println(t1.getName());
        }
    }
    
    class TT{
        private String name;
    
        public TT (String name) {
            this.name = name;
        }
    
        public String getName() {
            return this.name;
        }
    
        public void setName(String name1) {
            this.name = name1;
        }
    }
    

    上一篇:如何理解 Java 中的继承?

    下一篇:Java 的操作符——“=”号

    微信搜索「沉默王二」公众号,关注后回复「免费视频」获取 500G Java 高质量教学视频(已分门别类)。

    展开全文
  • 对于代码: ...如果这个语句出现函数内部,那么它就在栈上创建对象。 如果这个语句不是函数内部,而是作为一个类的成员变量,则取决于这个类的对象是如何分配的。 class Class { Object obj; };...

    对于代码:
    Object obj;
    obj是在栈上分配的嘛?
    其实,这个语句的含义是,使对象obj具有“自动存储的性质”,意思就是这个对象的存储位置取决于其声明所在的上下文。
    如果这个语句出现在函数内部,那么它就在栈上创建对象。
    如果这个语句不是在函数内部,而是作为一个类的成员变量,则取决于这个类的对象是如何分配的。

    class Class
    {
        Object obj;
    };
    
    Class *pClass = new Class;

    指针pClass所指向的对象在堆上分配空间。因为Object obj;语句的含义是“自动存储”,所以,pClass->obj也是在堆上创建的。

    Object *pObj;
    pObj = new Object;

    Object *pObj;代表,指针pObj是自动存储的,仅此而已,没有任何其它含义。而下面一行语句则指出,这个指针所指向的对象是在堆上面分配的。

    至此,我们解释了函数内部的变量和成员变量。还有两类变量:全局变量和static变量。它们即不在堆上创建,也不在栈上创建。它们有自己的内存空间,是除堆和栈以外的数据区。也就是说,当Object obj即不在函数内部,又不是类的成员变量时,这个对象会在全局数据段创建,同理适用于static变量。对于指针Object *pObj;,如果这个语句出现在函数内部或类的成员变量,正如我们前面所说的,这个指针是自动存储的。但是,如果这个语句是在类的外部,它就是在全局数据段创建的。虽然它指向的对象可能在堆上创建,也可能在栈上创建。

    **堆和栈的区别在于两点:
    1.生命周期
    2.性能**
    第一点才是我们需要着重考虑的。由于栈的特性,如果你需要一个具有比其所在的上下文更长的生命周期的变量,只能在堆上创建它。所以,我们的推荐是:只要能在栈上创建对象,就在栈上创建;否则的话,如果你不得不需要更长的生命周期,只能选择堆上创建。这是由于在栈上的对象不需要我们手动管理内存。有经验的开发人员都会对内存管理感到头疼,我们就是要避免这种情况的发生。总的来说,我们更多推荐选择在栈上创建对象。

    但是,有些情况,即便你在栈上创建了对象,它还是会占用堆的空间。考虑如下代码:

    void func
    {
        std::vector v;
    } 

    对象v是在栈上创建的。但是,STL 的vector类其实是在堆上面存储数据的(这点可以查看源代码)。因此,只有对象v本身是在栈上的,它所管理的数据(这些数据大多数时候都会远大于其本身的大小)还是保存在堆上。

    展开全文
  • C++ 栈对象 堆对象 理解

    千次阅读 多人点赞 2014-08-20 16:20:00
    1、静态建立类对象:是由编译器为对象在栈空间中分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造函数。 2、动态建立类对象...
  • 栈对象堆对象和静态对象比较

    千次阅读 2018-08-09 14:01:49
    而且栈对象的创建速度一般较堆对象快,因为分配堆对象时,会调用operator new操作,operator new会采用某种内存空间搜索算法,而该搜索过程可能是很费时间的,产生栈对象则没有这么麻烦,它仅仅需要移动栈顶指针就...
  • 如果需要在堆上创建对象,要么使用new运算符,要么使用malloc系列函数。这点没有异议。 真正有异议的是下面的代码: Object obj; 此时,obj是在栈上分配的吗? 要回答这个问题,我们首先要理解这个语句是什么...
  • Java对象与引用变量,在堆区区的存放原理 Student stu; //1、在栈内存里面开辟了空间给引用变量stu stu = new Student(); //2、new Student()堆内存里面开辟了空间给Student类的对象,只是这个对象还没有...
  • 栈对象堆对象

    2008-10-10 17:38:00
    gameres上看见一个问题帖:什么时候该用 Object object;什么时候该用 Object *object;...引用一下别人对栈对象堆对象的解释: 栈对象的优势是适当的时候自动生成,又适当的时候自动销毁,不需要程序员操心
  • 而且栈对象的创建速度一般较堆对象快,因为分配堆对象时,会调用operator new操作,operator new会采用某种内存空间搜索算法,而该搜索过程可能是很费时间的,产生栈对象则没有这么麻烦,它仅仅需要移动栈顶指针就...
  • C++只在栈上实例化对象

    千次阅读 2017-03-10 14:42:26
    C++如何让类对象只能在堆)上分配空间一般情况下写一个类都是可以采用new在堆上分配空间,或直接采用 类名+对象名 的方式在栈上分配空间。但有时候,如果想让一个类只能在栈上或者上分配空间,又该怎么实现呢...
  • 一般情况下,编写一个类,是可以在栈或者分配空间。但有些时候,你想编写一个只能在栈或者只能在堆上面分配空间的类。这能不能实现呢?仔细想想,其实也是可以滴。C++中,类的对象建立分为两种,一种是静态建立...
  • 浅谈堆、堆区区的概念和区别

    万次阅读 多人点赞 2019-10-21 15:45:15
    以前小编我对于这几个名词真的是分不清,感觉好像都一样,因为概念很抽象,不知道大家有没有这样觉得,所以我觉得有必要要对它进行区分下,让大家对它起码有宏观的认识。 一、区别 注:首先可以分为两种,...
  • 万次阅读 2015-03-16 11:46:46
    堆区:村线程操纵的数据(对象形式存放)1 存储的全部是对象,每个对象包含一个与之对应的class信息--class的目的是得到操作指令2 jvm...对象都存放在堆区中。2 每个战中的数据(基础数据类型和对象引用)都是私有的,
  • Person p =new Person(“张三”,20); 这样的,我可不可以这样理解new Person(“张三”,20)在堆内存中创建,分配...Person p 在栈内存中创建,然后把内存中的内存地址付给内存中的p变量 我这样理解有错误吗
  • C++堆还是栈上创建对象

    千次阅读 2016-08-18 11:31:39
    关于究竟是在堆还是在栈上创建对象,可能很多初学者感到迷惑。我想可以把这部分内容拿出来详细介绍一下。现在,假设你已经清楚什么是,什么是。如果需要在堆上创建对象,要么使用new运算符,要么使用malloc...
  • 关于究竟是在堆还是在栈上创建对象,可能很多初学者感到迷惑。我想可以把这部分内容拿出来详细介绍一下。现在,假设你已经清楚什么是,什么是。如果需要在堆上创建对象,要么使用new运算符,要么使用malloc...
  • 细说JVM系列:成员变量分配在栈还是堆中?下午时小伙伴问了我一个问题:mAge为啥是在堆里?幸好最近我一直学习JVM,所以我思考了一会结合之前的资料给出了我的理由: 因为mAge是类的成员变量,既然类的对象在...
  • Java中对象到底存在还是栈

    千次阅读 2020-07-30 14:50:02
    创建一个对象的时候,到底是在栈中分配还是在堆中分配需要看2个方面:对象类型和Java中存在的位置 1.如果是基本数据类型,byte、short、int、long、float、double、char,如果是方法中声明,则存储在栈中,其它...
  • 数据区、代码区、区、堆区

    千次阅读 2015-01-04 10:10:06
    堆区(heap):由程序员决定,Java中,如果程序员不释放的话,一般会由垃圾回收机制自动的清理掉。此区域主要用来存放我们经常创建的对象、动态的申请的临时空间等。  3.数据区(data seg):也称全局区或者静态区,根
  • 昨天一个同学去网易面试C++研发,问到了这么一个问题:如何限制一个类对象在栈)上分配空间? 一般情况下,编写一个类,是可以在栈或者分配空间。但有些时候,你想编写一个只能在栈或者只能在堆上面分配...
  • 与堆、区与堆区----两者的区别

    千次阅读 2018-06-13 08:39:38
     2、内存模型里面的区和堆区和数据结构没有关系,底层也不是讲用了数据结构里面的堆栈的存储方式。但是类似,区(stack) 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构...
  • 只能在栈上或者上创建对象

    千次阅读 2010-05-29 20:50:00
    C++中存放变量的地方有三个,分别是全局/静态变量存储,局部变量存储,new存放的变量存放在堆上,解题的思路是:如果只在栈上创建对象则禁止在堆上创建,重写operator new 和operator delete如果只在堆上...
  • 的精华大总结

    万次阅读 多人点赞 2019-11-18 18:37:41
    :存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 ◆:存放用new产生的数据 ◆静态域:存放在对象中用static定义的静态成员 ◆常量池:存放常量 ◆非RAM存储:硬盘...
  • c++中堆对象栈对象

    千次阅读 2012-03-06 21:02:31
     栈对象适当的时候创建,然后适当的时候自动释放的,也就是栈对象有自动管理功能。那么栈对象什么会自动释放了?第一,其生命期结束的时候;第二,其所在的函数发生异常的时候。你也许说,这些都很...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 274,044
精华内容 109,617
关键字:

对象在栈区还是堆区