学习笔记--cpp内存管理(侯捷)

cpp memory

1. 基础知识

  • 使用memory的每一层面

    结构
  • new、delete、array new/delete、replacement new是运算符且不可被重载,而operator new/delete 是函数,可以被重载。

1.1 new

  • 用于动态创建一个对象。Person *p = new Person("name");

  • 编译器会将该运算符其转换为以下步骤。

    1. 通过operator new 获得一片内存的指针。
      • 实际上也是调用malloc。但保证不抛出异常。
    2. 将该指针强制转换成需要的指针Person *
    3. 通过指针调用该类的构造函数。
      • p->Person::Person("rui"),只有编译器才可以这样。

1.2 delete

  • 删除new创建的内存。

    code
    Person *p = new Person("name");
    ...
    delete p;
    
  • 编译器将其转换为以下步骤。

    1. 调用析构函数。p->~Person()
    2. operator delete该对象内存。
      • 实际上是调用free。但保证不抛出异常。

1.3 array new/delete

  • 创建或删除连续多个对象的内存。

    code
    Person *p = new Person[3];
    //必须要有默认构造方法
    //无法由参数给予初值
    delete [] p;  //若不用[]可能会导致内存泄漏
    
  • delete内存泄漏,实际上是因为只调用了一次析构函数,而其他对象的析构函数没有执行,最终导致泄漏。

    code
    int *pi = new int[3];
    ...
    //下面语句效果与 delete [] pi; 相同 但建议加上
    //因为int没有指向其他地方的内存,也没有析构函数,所以不会造成内存泄漏
    delete pi;
    

1.4 replacement new

  • 定位new运算符,允许将对象分配到已经分配的内存中。需要包含new头文件。

    • 等同于调用构造函数(编译器行为)。
    • 需要显式为每个对象调用析构函数(如果存在)
    • 应以创建顺序相反的顺序进行删除,(晚创建的对象可能依赖于早创建的对象)
    • 当所有对象都被销毁后才能释放存储这些对象的缓冲区。
    code
    //缓冲区
    char *buffer = new char[12];
    
    int *p1 = new (buffer) int;
    int *p2 = new (buffer+4) int;
    delete [] buffer;     //直接释放缓冲区,则会释放p1,p2指向的数据
    
    char *buffer2 = new char(sizeof(string)*2);
    Person *person1 = new(buffer2) Person("rui1");
    Person *person2 = new(buffer2+sizeof(Person)) Person("mm");
    //显式逆序调用析构函数,释放名字存放内存
    person2->~Person();
    person1->~Person();
    //最后释放缓冲区
    delete [] buffer2;
    

1.5 overload

  • 应用程序内存分配途径
    应用程序内存分配途径
  • 容器类分配内存的途径
    容器类分配内存的途径
  • 可以重载operator new/delete与operator new[] /dlelete[] ,详细示例--AU:zedjay_

2. memory allocator

内存分配器

  • 目的是减少malloc的使用次数,提高速度、节省空间。
    • 每次malloc会增加多余的信息(cookie,一般4byte)
    • 头和尾都带有cookie,共需要多分配8字节的空间。
  • 通过自定义的operator new/deleteoperator new[]/delete[]等,来实现自定义的内存分配。
  • std::alloc 的运行模式,详细过程--小瓶子的笔记本
    运行模式

3.malloc/free

posted @ 2021-10-13 21:34  Oniisan_Rui  阅读(378)  评论(0)    收藏  举报