C++ - 动态内存

内存

  • 静态内存:static对象,在使用前分配,程序结束销毁
  • 栈内存:保存定义在函数内的非static对象,仅在其定义的程序块运行时才存在

智能(smart)指针

  • 头文件<memory>
  • shared_ptr <T> sp允许多个指针指向同一对象
    • 有一个关联计数器,称为引用计数(reference count)
    • 一旦计数器变为0,即自动释放管理的对象(类似于析构函数)
  • unique_ptr <T> up独占所指向的对象
  • make_shared标准库函数:最安全分配使用动态内存的方法 shared_ptr<int> p = make_shared<int>(42)
  • 注意事项
    • 不要混合使用智能指针和普通指针
    • 不要用get初始化另一个智能指针或为其赋值
  • weak_ptr
    • 不控制所指对象生存期的智能指针,将一个弱指针绑定在共享指针上不会改变共享指针的引用计数
    • 一旦最后一个共享指针被销毁,对象即被释放

使用动态内存原因

  • 程序不知道自己需要多少对象
  • 程序不知道所需对象的准确类型
  • 程序需要在多个对象间共享数据(允许多个对象共享相同的状态,如string拷贝赋值)

手动动态内存分配

  • new时内存耗尽
    • 抛出std::bad_alloc
    • new (nothrow) int解决 返回一个空指针 即定位(placement) new
  • delete
    • 两个动作:销毁给定指针指向的对象,释放对应的内存
    • 行为未定义:释放一块非new分配的内存,或将同一指针释放多次
    • 由内置指针管理的动态内存在被显式释放之前一直存在
    • 在删除内存后记得将指针置空,避免空悬指针(dangling)
  • new T [ ]分配动态数组
    • 不可用范围for语句处理动态数组中的元素,因没有数组维度
    • unique_ptr<int[]> up (neq int [10])
    • delete [] p
  • newdelete很大的问题在于绑定了内存分配和对象构造
  • allocator类 同样在<memory>
    • allocator<T> a分配的内存是未构造的(unconstructed)
    • a.allocate(n)分配一段原始的、未构造的内存,保存n个类型为T的对象