C++:从栈和堆来理解C#中的值类型和引用类型

C++中并没有值类型和引用类型之说,标准变量或者自定义对象的存取默认是没有区别的。但如果深入地来看,就要了解C++中,管理数据的两大内存区域:栈和堆。

栈(stack)是类似于一个先进后出的抽屉。它的体积是有限的,一般为2M左右。

而堆(heap)则相对来说体积可以很大,这一般跟计算机的虚拟内存设置有关系。

栈中存取对象的内存是自动回收的,用完即销毁了,一般方法内部的变量和参数都是通过栈来存取的(但也正因为如此,它们的生命周期很短)。但它的问题是,体积有限。

一些大的对象,我们可能要通过堆来创建它。程序员可以控制这些对象什么时候创建,什么时候销毁。这无疑带来了灵活性,也同时带来了一些风险,事实上,相当一部分的程序的崩溃都是因为不恰当地使用了堆,以及没有及时清理在堆上申请的内存。或者反过来说,可能会清理多次(这也会导致崩溃)。

通常来说,如果希望某个对象或者变量的生命更长一些,也可以将其作为全局变量或者静态变量。但那样又导致了它们必须等到程序结束才会释放。

下面我用一个例子来演示一下这个问题

#include <iostream>
using namespace std;

class human{
public:
    void Talk();
    ~human(){cout<<"析构函数在工作..."<<endl;}
private:
    int age;
};

void human::Talk(){
    cout<<"Hello"<<endl;
}

int main()
{
    human h;//创建一个human对象,这个对象就生存在栈上,它所需的大小是根据其成员决定的
    cout<<"h的大小为:"<<sizeof(h)<<endl;
    cout<<"h的地址是:"<<&h<<endl;
    h.Talk();

    human *p=new human();//通过new关键字,是在堆上面创建一个对象,它所申请的空间也是内部成员决定的.这里也是4
    cout<<"p的大小为:"<<sizeof(p)<<endl;
    cout<<"p的地址为:"<<p<<endl;
    p->Talk();
    delete p;
    //删除p这个指针指向的堆上面的内存.如果用完该对象,我们不删除,那么该内存就一直存在,并不会自动删除.这就称为内存泄漏.
    //如果类型定义了析构函数,此时将调用它(反之,如果一个对象是在堆上创建的,那么除非调用delete语句,否则析构函数不会运行
    cout<<"p的地址为:"<<p<<endl;//我们只是删除了该块内存上面的数据,地址还是存在的
    //建议在删除p之后,将其置为0
    //p=0;
    //delete p;//但如果再次删除,又会发生崩溃,因为该内存已经没有了.
    return 0;
}

时间: 2024-10-03 21:25:22

C++:从栈和堆来理解C#中的值类型和引用类型的相关文章

深入理解PHP变量的值类型和引用类型_php实例

在PHP中,大部分变量类型,如字符串,整型,浮点,数组等都是值类型的,而类和对象是引用类型,在使用的时候,需要注意这一点. 看到网友在讨论PHP的&符号,要彻底理解它的用法,就有必要讨论一下变量的两种形式. PHP的变量在内存中是这样存储的,变量保存的并不直接是值的内容,而是地址.例如: $a = 1; 我们看起来,似乎变量$a直接存储了 1 这个值.而实际情况是,PHP解释器创建了变量$a,将值:1 存入内存中的某个地方,再将值的地址存到变量$a中. 需要取值时,先找到变量$a中的地址,再根据

.NET中的六个重要概念:栈、堆、值类型、引用类型、装箱和拆箱

内容导读 •概述 •当你声明一个变量背后发生了什么? •堆和栈 •值类型和引用类型 •哪些是值类型,哪些是引用类型? •装箱和拆箱 •装箱和拆箱的性能问题一.概述 本文会阐述六个重要的概念:堆.栈.值类型.引用类型.装箱和拆箱.本文首先会通过阐述当你定义一个变量之后系统内部发生的改变开始讲解,然后将关注点转移到存储双雄:堆和栈.之后,我们会探讨一下值类型和引用类型,并对有关于这两种类型的重要基础内容做一个讲解. 本文会通过一个简单的代码来展示在装箱和拆箱过程中所带来的性能上的影响,请各位仔细阅读

值类型、引用类型 再次理解

 重新理解一下C#中的值类型和引用类型,在以前读<C#高级编程(第三版)>时,也是粗略看了一下,没有在意,直到今天,重新认识了这个东西. 一.值类型:存储在堆栈中:引用类型:存储在托管对上: 二.值类型进行"="操作时,会创建值类型的复制版本: 值类型: int i = 20; int j= i; Console.WriteLine(string.Format("i={0}/tj={1}", i.ToString(), j.ToString())); /

理解C#中的string类型

目的 本文的目的在于揭示和DOTNET及C#相关的一些常见的和不常见的问题.在这些问题中我的第一篇文章和string数据类型有关,string数据类型是一种引用类型,但是当和其他引用类型比较的时候,很多开发人员可能并不能完全理解它的行为. 问题 对于常见的引用类型,当改变一个对象别名的值时,这种变化也同样会在一个实际的对象中表现出来;反之亦然.但是对于string类型,似乎不是这样的. 解释 引用类型 假设我们有一个类MyType,这个类有一个属性Name;我们还有一个类AppType,这个类提

值类型和引用类型的区别深入理解_实用技巧

区别: 1.值类型通常被分配在栈上,它的变量直接包含变量的实例,使用效率比较高. 2.引用类型分配在托管堆上,引用类型的变量通常包含一个指向实例的指针,变量通过该指针来引用实例.3.值类型继承自ValueType(注意:而System.ValueType又继承自System.Object):而引用类型继承自System.Object. 4.值类型变量包含其实例数据,每个变量保存了其本身的数据拷贝(副本),因此在默认情况下,值类型的参数传递不会影响参数本身:而引用类型变量保存了其数据的引用地址,因

深入理解Java中的字符串类型_java

1.Java内置对字符串的支持: 所谓的内置支持,即不用像C语言通过char指针实现字符串类型,并且Java的字符串编码是符合Unicode编码标准,这也意味着不用像C++那样通过使用string和wstring类实现与C语言兼容和Unicode标准.Java内部通过String类实现对字符串类型的支持.这意味着:我们可以直接对字符串常量调用和String对象同样的方法: //可以再"abc"上直接调用String对象的所有方法 int length="abc".l

基础才是重中之重~理解内存中的栈和堆

.NET中使用stack(栈)和heap(堆)两种结构在内存中存储数据,今天咱们就来说说这两个结构 Value Types,值类型      在C#中,值类型继承自System.ValueType的,它们分别是       Bool,   byte ,  char, decimal, double, enu, float, int, long, sbyte, short, struct, uint, ulong, ushort Reference Types 引用类型     引用类型包括所有的

一方面:int是值类型,int a 定义在栈上;另一方面int又继承自Object类,是个类,类的对象应该在堆上

问题描述 ①inta=newint();这种写法,a中存储的是地址吗?②有人说,int是个静态类,所以可以inta:这个说法对吗?③版主说,int是值类型,在编译的时候会自动进行装箱拆箱,请问inta=10在编译时会被装箱成对象吗(如果这样岂不是更复杂了)?④一方面:int是值类型,inta定义在栈上:另一方面int又继承自Object类,是个类,类的对象应该在堆上.这不是矛盾嘛? 解决方案 解决方案二:引用楼主sshziliao3的回复: ①inta=newint();这种写法,a中存储的是地

栈和堆(Stack &amp;&amp; Heap)

一.前言      直到现在,我们已经知道了我们如何声明常量类型,例如int,double,等等,还有复杂的例如数组和结构体等.我们声明他们有各种语言的语法,例如Matlab,Python等等.在C语言中,把这些变量放在栈内存中. 二.基础      1.栈           什么是栈,它是你的电脑内存的一个特别区域,它用来存储被每一个function(包括mian()方法)创建的临时变量.栈是FILO,就是先进后出原则的结构体,它密切的被CPU管理和充分利用.每次function声明一个新的