当前位置:主页   - 电脑 - 程序设计 - C/C++
C++ : 从栈和堆来理解C#中的值类型和引用类型
来源:网络   作者:陈希章   更新时间:2011-04-07
收藏此页】    【字号    】    【打印】    【关闭

  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;
}

其它资源
来源声明

版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明