• C++ 动态内存管理 new delete allocator shared_ptr


    1.在C++的程序中会有下面几块不同性质的内存来管理程序:

    静态内存:用来保存局部的static对象,类的static数据成员,定义在函数外的全局变量。静态内存在程序启动时开辟在程序结束时释放。由编译器自动创建和销毁。

    栈内存:用来保存函数内的非static对象(不包括用new开辟空间生成的对象)。在进入函数时开辟,才函数结束时释放。由编译器自动创建和销毁。

    堆内存:用来存储动态分配的对象,比如在C++中用new关键字创建的对象就放在堆内存中。这种动态对象的生存周期由程序自身控制。也就是说用new关键字创建的对象,需要我们手动去释放它所开辟的内存。比如在函数中用new声明了局部变量,如果没有手动释放该对象,那么即使函数运行完毕后该对象还是不会被销毁。

    2.new和delete

    new用于手动分配内存创建一个动态对象,它的返回值是一个对象的指针:

    int* i = new int();
    Person* p = new Person();
    Person* p = new Person[10];//new一个数组的时候返回的是对象的指针,指向数组的首元素
    delete用来销毁用new创建的动态对象释放内存:
    int* i = new int();
    delete i;
    Person* p = new Person();
    delete p;
    Person* p = new Person[10];
    delete [] p;//当销毁一个数组动态对象时需要加上[]
     
    3.allocator的使用,头文件:#include <memory>
    (1)使用new创建动态对象的时候,必须在分配内存的时候就对其进行初始化,就是在new的时候就会调用构造函数,同样delete的时候就会调用析构函数。
    (2)如果我们希望创建动态对象,并且将其为这个对象分配内存和初始化分开执行,就需要使用allocator
    (3)创建动态对象用法:
     std::allocator<string> alloc;//创建一个allocator对象它用来为分配string类型的对象分配内存
        std::string* p = alloc.allocate(10);//分配一个可以存储10个string对象的内存空间,返回的p指针指向可以存储的第一个string对象
        std::string* p1 = p;
        alloc.construct(p1,"hi");//为分配的内存中的第一个string对象初始化,这里第一个参数是指向这个内存位置的指针,后面就是string的构造函数支持的参数,只要string本身支持的构造方法这里都可以使用其来初始化p1
        cout<<*p1<<endl;
        std::string* p2 = p;
        alloc.construct(p1,10,'a');//为分配的内存中的第二个string对象初始化
        cout<<*p2<<endl;
    (4)销毁动态对象:
    首先要销毁在申请的这段内存中初始化赋值了的对象:
     alloc.destroy(p1);
     alloc.destroy(p2);
    然后回收分配的那段内存:
    alloc.deallocate(p,10);//这里的p是申请内存时返回的指针,10是申请时写入的长度
     
    4.智能指针的使用,头文件:#include <memory>
    (1)为了简化动态对象的管理,新的标准库提供了智能指针的用法,使用智能指针他会自动释放我们动态对象使用的内存
    (2)智能指针分为三种:std::shared_ptr允许多个指针指向同一个对象,std::unique_ptr独占所指向的对象,std::weak_ptr指向std::shared_ptr所管理的对象
    (3)创建智能指针:
    std::shared_ptr<int> ptr;//ptr中保存一个空指针
    推荐使用make_shared函数来创建智能指针:
    std::shared_ptr<std::string> ptr = std::make_shared<std::string>(10,'a');//make_shared支持所有该类型的构造函数
    (4)shared_ptr的计数功能,每个shared_ptr都有关联的计数器,当用一个shared_ptr初始化另一个shared_ptr时或者拷贝赋值或者作为函数参数传递或者作为返回值返回等,都会让这个计算器+1。当销毁这个shared_ptr指针对象时(一个局部shared_ptr离开作用域时)会让计数器-1。
    当这个计数器减少为0时,就会自动去销毁这个智能指针指向的对象,从而实现自动销毁释放对象的功能。shared_ptr有一个use_count()函数用来返回这个计数器的值。
    (5)可以使用new创建的动态对象初始化智能指针,默认会使用delete来销毁这个动态对象:
    std::shared_ptr<std::string> ptr2(new string("ssssssss"));
    也可以将普通指针放入括号里面来创建一个动态指针,但是没必要这样做,因为这样使用后反需要我们自己提供delete来销毁这个对象。
    (6)不要混用普通指针和智能指针!!!
    如果将一个智能指针绑定到一个普通指针之后,就将这个指针的内存管理交给了智能指针,也就是说如果这个智能指针被销毁后,普通指针有可能就访问不到自己指向的内存了。
  • 相关阅读:
    艾伟_转载:基于.NET平台的Windows编程实战(三)—— 项目的创建及主界面的设计 狼人:
    艾伟_转载:C# Design Patterns (2) Strategy 狼人:
    艾伟_转载:C# Design Patterns (5) Prototype 狼人:
    艾伟_转载:正则表达式30分钟入门教程 狼人:
    艾伟_转载:WCF安全之EndPointIdentity 狼人:
    艾伟_转载:老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现 狼人:
    艾伟_转载:.NET平台上的Memcached客户端介绍 狼人:
    艾伟_转载:关于.NET中的循环引用 狼人:
    艾伟_转载:VS 2008快捷键 狼人:
    艾伟_转载:Regex.Replace 方法的性能! 狼人:
  • 原文地址:https://www.cnblogs.com/maycpou/p/14709683.html
Copyright © 2020-2023  润新知