首页 > C/C++ > 侯捷-c++面向对象程序设计-学习笔记-08-堆、栈和内存管理

侯捷-c++面向对象程序设计-学习笔记-08-堆、栈和内存管理

2020年8月12日
分类: C/C++ 标签: ,

1,c++对象的内存分配方式及生命周期

c++中对象有4种内存分配方式:栈、堆、静态数据区、全局数据区。

  • 栈中变量
    •  在一段代码块中临时分配的变量。该变量在程序退出代码块时【自动】销毁。
    • 【需要准确理解“自动”的含义。在下边代码中,vl和p都是代码块中的局部变量,都在程序退出它们所在的代码块时被销毁。虽然p是一个指针,p所指的内存空间不会被自动释放,但是就p自身来说,这个指针占用的sizeof(int*)大小的内存还是会被自动释放的。】
  • 堆中变量
    • 通过new创建的变量,必须手动通过匹配的delete来释放
    • 【这种变量实际上同时占用栈和堆两种空间。new返回的指针位于栈,指针指向的空间位于系统堆。】
  • 静态变量
    • 由static修饰的变量。在程序执行到变量定义处从静态区分配内存,并在整个进程退出后才释放。
    • static变量可以定义在局部代码块中,只初始化一次。
  • 全局变量
    • 不被任何代码块包含的变量,生命周期和static变量类似。

以下代码展示了这4中不同的内存分配方式。

//全局变量
int vg=0;

void fn(){
    //静态变量
    static int vs=1;
}

int main(){
    //栈中分配的变量
    int vl=2;

    fn();

    //堆中分配的变量
    int* p=new int(3);
    delete p;

    return 0;
}

2,动态内存分配的运行机制

  • T* p = new T()
    • void* pv = operator new(sizeof(T))    //operator new会调用malloc(sizeof(T))
    • p = static_cast<T*>(pv)
    • p->T::T()    //T::T(p), p即this
    • new的作用就是:分配内存,转换指针类型,调用构造函数执行初始化
  • delete p
    • p->T::~T()    //T::~T(p)
    • operator delete(p)    //operator delete会调用free(p)
    • delete的作用就是:调用析构函数,释放内存

3,array new和array delete

  • 动态分配数组时,需要使用new T[N]这样的语法
  • 释放指向数组的动态空间时,需要使用delete[] p语法
  • 如果释放动态数组时使用delete p,【p指向的内存会正常释放】,但是会导致【只调用一次数组对象的析构函数】,如果数组中的对象都各自分配了动态内存,这些内存将不会得到完全释放,从而造成内存泄露。可使用以下代码进行验证。
    • #include <iostream>
      using namespace std;
      
      class A{
        public:
          ~A(){
              cout << ++i << endl;
          }
      
          static int i;
      };
      
      int A::i=0;
      
      int main()
      {
        A* p = new A();
        delete p;
        A::i=0;
        
        p = new A[3];
        delete[] p;
        A::i=0;
        
        p = new A[3];
        delete p;
        
        return 0;
      }

4,vc编译器中new的内存分配策略

  • vc中,内存块的对齐单位为16字节,如果内存块大小不够16字节的倍数,编译器会进行填充
  • 单个对象
    • 【4字节cookie | 32字节内存块控制信息 | 类成员变量 | 4字节内存块控制信息 | 4字节cookie】
    • cookie存放的是对齐后的整个内存块的大小,其最后一位为1表示内存块已分配,为0表示内存块已回收
  • 数组对象
    • 【4字节cookie | 32字节内存块控制信息 | 数组元素个数(4字节) | 数组元素 | 4字节内存块控制信息 | 4字节cookie】

 

————————-笔记分割线——————–

【侯捷老师推荐的书籍】

您可能需要这些【参考资料】:
零一积流|IT参考 原创文章,转载请注明出处: http://www.it-refer.com/2020/08/12/http-www-it-refer-com-2020-08-10-houjie-cplusplus-object-oriented-programming-08-heap-stack-and-memory-management


本文的评论功能被关闭了.