CppPrimer笔记 Chapter12 动态内存

来源:互联网 发布:cad怎么修改网络计划图 编辑:程序博客网 时间:2024/05/18 11:49

CppPrimer笔记 Chapter12 动态内存

标签: Cpp


  • CppPrimer笔记 Chapter12 动态内存
    • 动态内存与智能指针121
    • 动态数组122


动态内存与智能指针(12.1)

  • shared_ptr允许多个指针指向同一个对象
    指向shared_ptr所管理的对象
  • 智能指针可以认为是能记录有多少个指向相同对象,因而能在恰当时调用析构函数自动释放
  • 使用动态内存的三种原因
    • 程序不知道自己需要使用多少对象(动态数组)
    • 程序不知道所需对象的准确类型(第15章)
    • 程序需要在多个对象间共享数据(通过类成员取值shared_ptr来构建一个可以共享的,会自动销毁的对象)
  • delete一个指针后,指针值变为无效.但仍保存了已经释放了的动态内存的地址.为悬空指针
  • delete一个动态分类的对象的指针时将执行析构函数
  • 接受指针参数的智能指针构造函数是explicit(禁止隐式类型转换)因而
    shared_ptr<int> p1 = new int(1024);//error    shared_ptr<int> p2(new int(1024)); //okshared_ptr<int>clone(int p){    return new int(p);} //errorshared_ptr<int>clone(int p){    return shared_ptr<int>(new int(p));} //ok
  • 不要混合使用普通指针与智能指针,也不好使用get初始化另一个智能指针,或为智能指针赋值
    void process(shared_ptr<int> ptr){}   int *x(new int(1024));   process(x);//error int*不能转化为shared_ptr<int>   process(shared_ptr<int>(x));   int j = *x;//未定义:x在process中被释放了   shared_ptr<int> p(new int(42));   int *q = p.get();   {shared_ptr<int> g(q);}//new block end,g释放了p的对象   int foo = *p;//未定义 使用悬空指针
  • 发生异常时,直接管理的内存是不会被自动释放的
  • shared_ptr<connection>p(&c,end_connection);会调用end_connection来进行销毁,这时c 不是由new分配的内存 也务必调用删除器而不是默认的delete
  • unique_ptr 独占所指向的对象,
    构建时需要绑定到一个new返回的指针上,同样只能采用直接初始化.
    由于为独占,不支持拷贝操作,
    但可以用release()reset将(非const unique_ptr)指针的所有权进行转移.注意release()放弃指针时造成的指针丢失
    release()对于指针类型,会销毁管理的指针(调用delete[])
  • unique_ptr<objT,delT>p(new objT,fcn)其调用自定义删除函数类似关联容器而与shared_ptr有区别
  • weak_ptr为弱引用,将weak_ptr绑定到一个shared_ptr,
    但不会改变shared_ptr的引用计数,因而可能会不存在,要利用lock来访问

动态数组(12.2)

  • allocator为了使得内存分配与对象初始化分离.进而可以没有默认构造函数也可以动态分配内存
  • 使用allocator
    allocator<string> alloc;    int n = 10;    auto const base = alloc.allocate(n);    auto q = base;    alloc.construct(q++);    alloc.construct(q++,10,'c');    alloc.construct(q++,"hi");    cout<<*p<<endl;    while(q != p)alloc.destroy(--q);    alloc.deallocate(p,n);
        vector<int> vec{ 1, 2, 3, 4, 5 };    allocator<int>alloc;    auto const base = alloc.allocate(vec.size()*2);    auto q = uninitialized_copy(vec.begin(), vec.end(), base);    q = uninitialized_fill_n(q, vec.size(), 42);    //注意 打印为倒序,42 42 42 42 42 5 4 3 2 1    while (q != base){ cout << *(--q) << endl; }
0 0