📂C/C++
2021-10-13 21:34阅读: 334评论: 0推荐: 0

学习笔记--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
    copy
    • 1
    • 2
    • 3
    Person *p = new Person("name"); ... delete p;
  • 编译器将其转换为以下步骤。

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

1.3 array new/delete

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

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

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

1.4 replacement new

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

    • 等同于调用构造函数(编译器行为)。
    • 需要显式为每个对象调用析构函数(如果存在)
    • 应以创建顺序相反的顺序进行删除,(晚创建的对象可能依赖于早创建的对象)
    • 当所有对象都被销毁后才能释放存储这些对象的缓冲区。
    code
    copy
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    //缓冲区 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

本文作者:oniisan

本文链接:https://www.cnblogs.com/oniisan/p/cppMemory.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Oniisan_Rui  阅读(334)  评论(0编辑  收藏  举报
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
点击右上角即可分享
微信分享提示