zoukankan      html  css  js  c++  java
  • C++ stack与heap

    stack(栈) heap(堆)
    Stack,是存在于某作用域(scope)的一块内存空间(memory space).例如当你调用函数,函数本身即会形成一个stack用来放置它所接收的参数,以及返回地址。

    在函数本身(function body)内声明的任何变量,其所使用的内存块都取自于上述stack.

    Heap,或者说system heap,是指由操作系统提供的一块global内存空间,程序可动态分配(dynamic allocated)从中获得若干区块(blocks)

    class Complex {...};
    ...
    {
    Complex c1(1,2);// c1所占用的空间来自stack
    Complex * p = new Complex(3); 
    //Complex(3)是个临时对象,其所占用的空间是以new自heap动态分配而得,并由p指向
    }

    stack objects 的生命周期

    class Complex{...};
    ...
    
    {
    Complex c1(1,2);
    }

    c1便是所谓stack object,其生命在作用域(scope)结束时结束。
    这种作用域内的object,又称为auto object,因为它会被自动释放。


    static local objects 的生命周期

    class Complex{...};
    ...
    
    {
    static Complex c2(1,2);
    }

    c2便是所谓static object,其生命在作用域(scope)结束时仍然存在,直到整个程序结束.

    class Complex{...};
    ...
    Complex c3(1,2);
    
    int main()
    {
    ...
    }

    c3就是global object,其生命在整个程序结束之后才结束,也可以把它视为一种static object,其作用域是整个程序.


    heap objects 的生命周期

    class Complex{...};
    ...
    
    
    {
    Complex* p = new Complex;
    ...
    delete p;
    }

    p所指的是heap object,其生命在它被deleted时结束。

    class Complex{...};
    ...
    
    
    {
    Complex* p = new Complex;
    }

    以上出现内存泄露(memory leak),因为当作用域结束,p所指的heap object仍然存在,但指针
    p的生命却结束了,作用域之外再也看不到p(也就没机会delete p)了。
    尽可能避免这种情况。

    new:先分配memory,再调用ctor

    Complex * pc = new Complex(1,2);

    三个步骤。
    编译器转化为:

    Complex * pc;
    
    // operator new是C++中的一个特殊函数,其本质也是调用了malloc分配内存
    1.void * mem = operator new(sizeof(Complex)); 
    2.pc = static_cast<Complex*>(mem); //将mem指针转为Complex类型的指针
    3.pc->Complex::Complex(1,2); //构造函数 本质 Complex::Complex(pc,1,2); 这里的pc相当于this,是不可见的

    delete: 先调用 dtor,再释放memory

    String * ps = new String("Hello");
    ...
    delete ps;

    编译器转为
    String::~String(ps); //析构函数
    operator delete(ps); //释放内存,operator delete()是C++中的一个特殊函数其内部调用free(ps)

    array new 一定要搭配 array delete

    String * p = new String[3];
    ...
    delete[] p; //唤起3次dtor

    String * p = new String[3];
    ...
    delete p; //唤起1次dtor

  • 相关阅读:
    化零为整WCF(5) 宿主Hosting(宿主在IIS, Application, WAS, WindowsService)
    使用Aspose.Cell控件实现Excel高难度报表的生成(三)
    Winform开发框架之动态指定数据表
    Winform分页控件之纯分页显示处理
    利用Aspose.Word控件实现Word文档的操作
    代码生成工具之Winform查询列表界面生成
    代码生成工具之界面快速生成
    Winform开发中手写签名的实现
    代码生成工具之数据库表及字段名称转义
    Winform开发框架之通用附件管理模块
  • 原文地址:https://www.cnblogs.com/xiangqi/p/14273063.html
Copyright © 2011-2022 走看看