草庐IT

c++ - 加速 C++ 练习 11-6

coder 2024-02-09 原文

在 ch 11 练习 11-6 中卡在了删除函数中。我已经销毁了对象,但我不知道如何使用分配器库中的释放来返回空间。

请保释我。 PS : 这不是作业,但我在家练习

下面是来自 Accelerated C++ 的代码,之后是我修改过的删除函数。 谢谢`

template <class T> class Vec
{
public:
    typedef T* iterator;
    typedef const T* const_iterator;
    typedef size_t size_type;
    typedef T value_type;
    typedef T& reference;
    typedef const T& const_reference;

    Vec() { create(); }
    explicit Vec(size_type n, const T& t = T()) { create(n, t); }
    Vec(const Vec& v) { create(v.begin(), v.end()); }
    Vec& operator=(const Vec&);
    ~Vec() { uncreate(); }

    T& operator[](size_type i) { return data[i]; }
    const T& operator[](size_type i ) const { return data[i]; }

    void push_back(const T& t)
    {
        if (avail == limit)
        {
            grow();
        }

        unchecked_append(t);
    }

    iterator erase(iterator);
    iterator erase( iterator, iterator );
    void clear();

    size_type size() const { return avail - data; }

    iterator begin() { return data; }
    const iterator begin() const { return data; }

    iterator end() { return avail; }
    const iterator end() const { return avail; }

private:
    iterator data;
    iterator avail;
    iterator limit;

    std::allocator<T> alloc;

    void create();
    void create(size_type, const T&);
    void create(const_iterator, const_iterator);

    void uncreate();

    void grow();
    void unchecked_append(const T&);
};

我的代码

 template <class T> typename Vec<T>::iterator Vec<T>::erase(iterator  first, iterator second )
{
    if( second < first )
    {
        throw std::out_of_range("Iterator out of bounds.");
    }
    if( first < data || second >= avail )
    {
        throw std::out_of_range("Iterator out of bounds.");
    }
    iterator last = avail -1 ;
    iterator i = first ;
    iterator j = second ;  
    while( j <= last )
    {
        *i++ = *j++ ;

    }
    // destroy each initilsed space 
    iterator new_avail =  avail -  first + second ;

    std::cout << " end " << end() << std::endl;

    while( avail != new_avail )
    {
        alloc.destroy(--avail ) ;
    }


    // dellocate  space how to do  that ?
    alloc.deallocate( avail -1,  );  // not sure  what to do  here 
    return first ;

}

最佳答案

您不能释放已分配内存的一部分。 那个

alloc.deallocate( avail -1, );

不好。

编辑

您不应该尝试在删除中管理分配。 您有一个选择是重新分配它,这将使删除更多 昂贵的。第二个功能可以做:

iterator shrink(iterator first, iterator last) {

    size_type capacity = (limit - data) - (last - first);

    iterator new_data = alloc.allocate(capacity);
    iterator new_avail = new_data;
    iterator source = data;
    while(source < first)
        // C++11
        alloc.construct(new_avail++, std::move(*source++));
    source = last;
    iterator result = new_avail;
    while(source < avail)
        // C++11
        alloc.construct(new_avail++, std::move(*source++));
    while(data < avail)
        alloc.destroy(--avail);
    data  = new_data;
    avail = new_avail;
    limit = new_data + capacity;

    return result;
}

更好的选择是这种标准方式。添加一个额外的构造函数, 交换和收缩以适应:

Vec(const_iterator first, const_iterator last) {
    create(first, last);
}

void swap(Vec& other) {
    std::swap(data, other.data);
    ...
}

bool shrink_to_fit() {
    try
    {
        Vec(begin(), end()).swap(*this);
        return true;
    }
    catch(...) {}
    return false;
}

现在您可以对 vector 应用多个操作并最终减少内存消耗。

 v.erase(a, b);
 v.erase(c, d);
...
v.shrink_to_fit();

关于c++ - 加速 C++ 练习 11-6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18984165/

有关c++ - 加速 C++ 练习 11-6的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  3. ruby - 安装libv8(3.11.8.13)出错,Bundler无法继续 - 2

    运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin

  4. 牛客网专项练习30天Pytnon篇第02天 - 2

    1.在Python3中,下列关于数学运算结果正确的是:(B)a=10b=3print(a//b)print(a%b)print(a/b)A.3,3,3.3333...B.3,1,3.3333...C.3.3333...,3.3333...,3D.3.3333...,1,3.3333...解析:    在Python中,//表示地板除(向下取整),%表示取余,/表示除(Python2向下取整返回3)2.如下程序Python2会打印多少个数:(D)k=1000whilek>1:    print(k)k=k/2A.1000 B.10C.11D.9解析:    按照题意每次循环K/2,直到K值小于等

  5. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  6. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  7. ruby - ri 有空文件 – Ubuntu 11.10, Ruby 1.9 - 2

    我正在运行Ubuntu11.10并像这样安装Ruby1.9:$sudoapt-getinstallruby1.9rubygems一切都运行良好,但ri似乎有空文档。ri告诉我文档是空的,我必须安装它们。我执行此操作是因为我读到它会有所帮助:$rdoc--all--ri现在,当我尝试打开任何文档时:$riArrayNothingknownaboutArray我搜索的其他所有内容都是一样的。 最佳答案 这个呢?apt-getinstallri1.8编辑或者试试这个:(非rvm)geminstallrdocrdoc-datardoc-da

  8. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  9. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

    出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

  10. ruby - Ruby 中字符串运算符 + 和 << 的区别 - 2

    我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc

随机推荐