C++标准库内存分配类allocator


1 C++定义两种直接分配内存与释放内存的函数

(1)创建内存空间并构造对象——new

(2) 析构对象并释放内存空间——delete

例:int *p =new int;//新建一个int大小的空间

  delete p;//释放相应的空间

(3)可以使用直接初始化的方式对分配的空间进行直接初始化。当我们未对分配的内存执行初始化时,该内存空间会执行默认初始化

例:vector<int> *pv=new vector<int>{0,1,2,3,4,5,6,7,8,9};

  string *p=new string("hello world!");

  string *p=new string;//默认初始化为空

(4)动态分配的内存其析构顺序与初始化顺序相反;

例:

#include<memory>
#include<iostream>
#include<string>

using namespace std;
class A {
    int a;    
public:
    A() :a(0)
    {
        cout << "Constructed!" <<a<< endl;
    }
    A(int a) :a(a)
    {
        cout << "Constructed!" <<a<< endl;
    }
    ~A()
    {
        cout << "Destructor!" << a<<endl;
    }
    int getValue() {
        return a;
    }
};

int main()
{
    int *pa = new int[10]{ 1,2,3,4,5,6,7,8,9,10 };

    A *p = new A[10]{ 1,2,3,4,5,6,7,8,9,10 };
    for (int i = 0; i < 10; i++)
    {
        cout << (p + i)->getValue() << endl;
    }
    delete[] p;
    cin.get();
}

(5)new与delete要匹配,分配内存之后必须要记得相应delete否则会造成内存泄漏,

2 allocator 类

(1)allocator类(包含<memory>头文件)

new在使用时将内存的分配与对象的构造结合在一起,但是,有时候,我们可能需要将内存的分配与对象的构造分离。这时候就需要allocator类发挥作用了

(2)allocator类的使用

1)allocator<T> a ;//定义一个allocator类对象

2)a.allocate(n);//分配n个T对象大小的空间

3) a.deallocate(p,n)//释放从T*指针p开始的n个T对象的内存。释放之间要先调用destory析构相应对象

4)a.construct(p,args);//将arg传给T的构造函数,利用p所指内存构造该对象.p为T*指针

5)a.destory(p)//p为T*指针,对p所指对象执行析构函数

3)a.destory(p)

例:

#include<memory>
#include<iostream>
#include<string>

using namespace std;
class A {
    int a;    
public:
    A() :a(0)
    {
        cout << "Constructed!" <<a<< endl;
    }
    A(int a) :a(a)
    {
        cout << "Constructed!" <<a<< endl;
    }
    ~A()
    {
        cout << "Destructor!" << a<<endl;
    }
    int getValue() {
        return a;
    }
};

int main()
{
    allocator<A> alloc;
    auto const p = alloc.allocate(5);
    auto q = p;
    for (int i = 0; i < 5; i++)
    {
        alloc.construct(q++, i);
    }
    for (auto it = p; it != q; it++)
    {
        cout << it->getValue() << endl;
    }
    for (auto it = p; it != q; it++)
    {
        alloc.destroy(it);
    }
    cin.get();
}

(3)allocator类算法

1)uninitialized_copy(begin,end,begin2);//将迭代器begin1~end(尾后迭代器)所代表的输入范围copy到begin2开始的内存,begin2所指向的内存必须大于begin~end所需的;

2)uninitialized_copy_n(begin,n,begin2);//从迭代器b指向的元素开始拷贝n个到begin2开始的内存空间

3)uninitialized_fill(begin,end,t);//在迭代器begin~end范围内构建t的拷贝;

4)uninitialized_fill_n(begin,n,t);//从begin开始的内存构建n个t的拷贝;

例:

#include<memory>
#include<iostream>
#include<string>
#include<vector>

using namespace std;
class A {
    int a;    
public:
    A() :a(0)
    {
        cout << "Constructed!" <<a<< endl;
    }
    A(int a) :a(a)
    {
        cout << "Constructed!" <<a<< endl;
    }
    ~A()
    {
        cout << "Destructor!" << a<<endl;
    }
    int getValue() {
        return a;
    }
};

int main()
{
    allocator<A> alloc;
    auto const p = alloc.allocate(10*10);
    auto q = p;
    vector<A> vec{ 0,1,2,3,4,5,6,7,8,9 };
    
    //q = uninitialized_copy(vec.begin(), vec.end(), p);
    q=uninitialized_copy_n(vec.begin(), 10, p);
    for (auto it = p; it != q; it++)
    {
        cout << it->getValue() << endl;
    }
    for (auto it = p; it != q; it++)
    {
        alloc.destroy(it);
    }
    cin.get();
}

参考书籍:

C++ Primer 5

学习笔记,不喜勿喷!!!

优质内容筛选与推荐>>
1、传输层
2、任意进制(2-36)到10进制的转化
3、C#客户端与Django服务器端对接——HTTP协议之POST&GET
4、Resource websites
5、ExtJS自定义事件


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn