allocator例子

13.39 编写自己的StrVec,包括自己版本的reserve、capacity和resize。

13.40 为StrVec添加一个构造函数,它接受一个initializer_list<string>参数

StrVec.h

#ifndef STRVEC_H
#define STRVEC_H
#include<iostream>
#include<string>
#include<utility>
#include<memory>
using namespace std;
class StrVec
{
public:
    StrVec():elements(nullptr),first_free(nullptr),cap(nullptr){}
    StrVec(const StrVec&);
    StrVec& operator=(const StrVec&);
    ~StrVec();
    void push_back(const string&);
    size_t size() const { return first_free-elements;}
    size_t capacity() const { return cap-elements;}
    string *begin() const  { return elements;}
    string *end() const { return first_free;}

    void reserve(size_t n);
    void resize(size_t n,string s=string());

    StrVec(initializer_list<string> il)
    {
        auto newcapacity=il.size();
        auto newdata=alloc.allocate(newcapacity);
        auto dest=newdata;
        auto elem=il.begin();
        while(elem!=il.end())
            alloc.construct(dest++,*elem);
        elements=newdata;
        first_free=cap=dest;
    }
private:
    static allocator<string> alloc;
    string *elements;
    string *first_free;
    string *cap;
    void chk_n_alloc()
    {
        if(size()==capacity()) reallocate();
    }
    pair<string*,string*> alloc_n_copy(const string*,const string*);
    void free();
    void reallocate();
};
#endif // STRVEC_H

StrVec.cpp

#include"StrVec.h"

allocator<string> StrVec::alloc;
StrVec::StrVec(const StrVec &s)
{
    auto newdata=alloc_n_copy(s.begin(),s.end());
    elements=newdata.first;
    first_free=newdata.second;
    cap=newdata.second;
}

StrVec& StrVec::operator=(const StrVec &s)
{
    auto data=alloc_n_copy(s.begin(),s.end());
    free();
    elements=data.first;
    first_free=cap=data.second;
    return *this;
}

StrVec::~StrVec()
{
    free();
}

void StrVec::push_back(const string &s)
{
    chk_n_alloc();
    alloc.construct(first_free++,s);
}

pair<string*,string*> StrVec::alloc_n_copy(const string *b, const string *e)
{
    auto data=alloc.allocate(e-b);
    return {data,uninitialized_copy(b,e,data)};
}

void StrVec::free()
{
    if(elements)
    {     //for_each(&first_free,&elements,[](string *p) { alloc.destroy(p);}); lambda式子
        for(auto p=first_free;p!=elements;)
            alloc.destroy(--p);
        alloc.deallocate(elements,cap-elements);
    }
}

void StrVec::reallocate()
{
    auto newcapacity=size()?2*size():1;
    auto newdata=alloc.allocate(newcapacity);
    auto dest=newdata;
    auto elem=elements;
    for(size_t i=0;i!=size();++i)
        alloc.construct(dest++,std::move(*elem++));
    elements=newdata;
    first_free=dest;
    cap=elements+newcapacity;
}

void StrVec::reserve(size_t n)
{
    if(capacity()<n)
        reallocate();
}

void StrVec::resize(size_t n,string s)
{
    if(size()<n)
        push_back(s);
    else if(size()>n)
    {
        for(auto p=elements+n;p!=first_free;)
            alloc.destroy(p++);
        first_free=elements+n;
    }
}
时间: 2024-08-02 07:49:51

allocator例子的相关文章

关于allocator的一些基础用法以及简易的vector实现

首先,关于allocator戳旁边→维基百科-分配器(C++) 这次我只用了其中的一部分API,来实现一个简易的vector容器,这个简易版vector实现了插入.删除.查找等简易功能,由于对右值的理解不足,所以这次并未实现关于右值的API. [MSDN-class allocator_base API] 此次用到的有: allocate - 用于分配.再分配空间 construct - 用于构造对象 destroy - 用于销毁对象(调用其构造函数) 接下来开始,用例子一点点的说明如何使用al

C++内存管理(超长,例子很详细,排版很好)

[导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须要过的,除非放弃C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由和对内存的支配权,还放弃了C++超绝的性能.本期专题将从内存管理.内存泄漏.内存回收这三个方面来探讨C++内存管理问题

《coredump问题原理探究》Linux x86版7.4节List coredump例子

看一个coredump例子: 看一个coredump例子: Core was generated by `./xuzhina_dump_c07_s2_ex'. Program terminated with signal 11, Segmentation fault. #0 0x0285b9b7 in std::_List_node_base::hook(std::_List_node_base*) () from /usr/lib/libstdc++.so.6 Missing separate

《coredump问题原理探究》Linux x86版7.2节vector coredump例子

看一个coredump的例子: [[email protected] s1_ex]$ gdb xuzhina_dump_c07_s1_ex core.27776 GNU gdb (GDB) Red Hat Enterprise Linux (7.2-75.el6) Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses

[转载] 彻底学习STL中的Allocator

原文: http://cissco.iteye.com/blog/379093 帮助我们理解allocator的原理 Allocator是C++语言标准库中最神秘的部分之一.它们很少被显式使用,标准也没有明确出它们应该在什么时候被使用.今天的allocator与最初的STL建议非常不同,在此过程中还存在着另外两个设计--这两个都依赖于语言的一些特性,而直到最近才在很少的几个编译器上可用.对allocator的功能,标准似乎在一些方面追加了承诺,而在另外一些方面撤销了承诺. 这篇专栏文章将讨论你能

【源码剖析】MemoryPool —— 简单高效的内存池 allocator 实现

什么是内存池?什么是 C++ 的 allocator? 内存池简单说,是为了减少频繁使用 malloc/free new/delete 等系统调用而造成的性能损耗而设计的.当我们的程序需要频繁地申请和释放内存时,频繁地使用内存管理的系统调用可能会造成性能的瓶颈,嗯,是可能,毕竟操作系统的设计也不是盖的(麻麻说把话说太满会被打脸的(⊙v⊙)).内存池的思想是申请较大的一块内存(不够时继续申请),之后把内存管理放在应用层执行,减少系统调用的开销. 那么,allocator 呢?它默默的工作在 C++

allocator class

当分配一大块内存时,我们通常计划在这块内存上按需构造对象,这样的我们希望将内存分配和对象构造分离.但是通常的new关键字的分配的动态空间,有时候会造成一些浪费,更致命的是“如果一个类没有默认构造函数,那么这个类就不能动态分配数组了”. 这时我们需要一个能将内存分配和对象构造分离的机制,allocator很好地帮助我们解决了这个问题. #include <memory>,allocator提供了一种类型感知的内存分配方法,它分配的内存是原始的,未构造的.我们可以利用allocator提供的操作对

c++ allocator

C++中,动态内存可以用new来实现,即在堆上申请空间,并需要显示释放这块动态内存.当然,也可以用智能指针来实现. new有一个缺陷,就是把内存分配和对象构造结合在了一起.对于单个对象,这是很方便的,然而对于大块的内存时,可能需要先申请空间,然后陆续执行构造,此时需要将内存分配和对象构造分离开来.allocator类就提供了这样的功能. 先来看一段使用new的例子: string* q = new string[10];//申请了10个stirng的空间,并进行默认初始化 string s; s

stl allocator源码学习

概述 介绍几个allocator的源码实现:简单的对operator new和operator delete进行封装的实现,vs2015中的实现,STLport中的实现,仿造STLport实现内存池. 1. 参考 http://www.cplusplus.com/reference/memory/allocator/ <STL源码剖析> <C++ Primer 第五版> <Generic Programming and the STL>(<泛型编程和STL>