zoukankan      html  css  js  c++  java
  • c++ allocator

    C++中,动态内存可以用new来实现,即在堆上申请空间,并需要显示释放这块动态内存。当然,也可以用智能指针来实现。

    new有一个缺陷,就是把内存分配和对象构造结合在了一起。对于单个对象,这是很方便的,然而对于大块的内存时,可能需要先申请空间,然后陆续执行构造,此时需要将内存分配和对象构造分离开来。allocator类就提供了这样的功能。

    先来看一段使用new的例子:

        string* q = new string[10];//申请了10个stirng的空间,并进行默认初始化
        string s;
        string *pp = q;
        while (cin >> s&&pp != q + 10)//再次为这些string赋值
            *q++ = s;
        delete[] q;

    可见,对象实际上执行了一次初始化和一次赋值,而实际上初始化的过程是不必要的。

    接下来,先用allocator重写一遍,然后再解释一下allocator的操作:

        allocator<string> alloc;//分配string类型的allocator
        auto p = alloc.allocate(10);//分配10个string空间
        auto q = p;
        string s;
        while (cin >> s&&q != p + 10)
            alloc.construct(q++, s);//用输入的值构造元素
        while (q != p)
            alloc.destroy(--q);//逐一销毁元素
        alloc.deallocate(p, 10);//释放内存空间

    首先,allocator是一个模板,需要指定分配内存的类型。allocator的主要操作如下:

        alloc.allocate(n);//分配一段原始的内存,保存n个元素,返回首地址
        alloc.construct(p, args);//在p的位置,用args调用构造函数,构造一个对象
        alloc.destroy(p);//对p指向的对象调用析构函数
        alloc.deallocate(p, n);//释放空间,注意n必须与分配的大小参数相等

    有几个地方需要注意:

    1.分配的内存是没有构造的,使用这些原始内存时错误的,也不能直接对这些内存进行赋值!

    2.构造后,如果想释放这块内存,需要先进行销毁,并且必须对构造过的元素进行销毁。

    3.分配和释放内存的大小必须相等。

    因为allocator可以方便地分配一段内存,于是标准库提供了两组函数,来对整段的区域进行创建对象的操作:

        uninitialized_copy(b, e, b2);//把迭代器b,e之间的元素拷贝到指针b2开始的内存中,b2内存足够大
        uninitialized_copy_n(b, n, b2);//从b起的n个元素拷贝到指针b2开始的内存中
        uninitialized_fill(b, e, t);//同上,对象的值均为t的拷贝
        uninitialized_fill_n(b, n, t);//同上,对象的值均为t的拷贝

    不过这些函数看到有人不推荐使用,VS中也会进行报错或者警告,因为是提供给内部使用的函数,前者推荐用copy和copy_n来代替,后者推荐用fill和fill_n来代替。

  • 相关阅读:
    css切图Sprites
    javascript改变position值实现菜单滚动至顶部后固定
    Cannot create type class java.io.File from value
    关于如何拍摄瓷器(转)
    Struts2的jar问题
    vim的基本操作
    Flask基础
    Flask入门
    MongoDB 之 数据类型
    基于DBUtils实现数据库连接池
  • 原文地址:https://www.cnblogs.com/lustar/p/7601009.html
Copyright © 2011-2022 走看看