vector的内存分配与释放

  1. vector内存分配数据结构

《Effective STL》中“条款14”:使用reserve来避免没必要要的从新分配app

关于STL容器,最神奇的事情之一是只要不超过它们的最大大小,它们就能够自动增加到足以容纳你放进去的数据。(要知道这个最大值,只要调用名叫max_size的成员函数。)对于vector和string,只要须要更多空间,就以realloc等价的思想来增加。这个相似于realloc的操做有四个部分:函数

  1. 分配新的内存块,它有容器目前容量的几倍。在大部分实现中,vector和string的容量每次以2为因数增加。也就是说,当容器必须扩展时,它们的容量每次翻倍。
  2. 把全部元素从容器的旧内存拷贝到它的新内存。
  3. 销毁旧内存中的对象。
  4. 回收旧内存。

给了全部的分配,回收,拷贝和析构,你就应该知道那些步骤都很昂贵。固然,你不会想要比必须的更为频繁地执行它们。若是这没有给你打击,那么也许当你想到每次这些步骤发生时,全部指向vector或string中的迭代器、指针和引用都会失效时,它会给你打击的。这意味着简单地把一个元素插入vector或string的动做也可能由于须要更新其余使用了指向vector或string中的迭代器、指针或引用的数据结构而膨胀。this

 DEMOspa

#include <QtCore/QCoreApplication>
#include <QDebug>
#include <vector>

using namespace std;

class Person
{
public:
        Person(QString str)
        {
            m_str=str;
            qDebug()<< "construction:"<<m_str;
        }
        Person(const Person& p)
        {
            this->m_str=p.m_str;
            qDebug()<< "copy construction:"<<m_str;
        }
        ~Person()
        {
            qDebug()<< "destruction:"<<m_str;
        }
    private:
        QString m_str;
};

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    {
        vector<Person> V;
        //V.reserve(10);

        qDebug()<<"MaxSize :"<<V.max_size()<<"Capacity :"<<V.capacity();

        Person a("a");
        Person b("b");
        Person c("c");

        qDebug()<<"  push :a";
        V.push_back(a);
        qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity();
        qDebug()<<"  push :b";
        V.push_back(b);
        qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity();
        qDebug()<<"  push :c";
        V.push_back(c);
        qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity();

        V.clear();
        qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity();

        //
        //vector<Person>(V).swap(V);
        //qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity();
    }

    return app.exec();
}

 

 

 

 

 

 

 

 

 

 

 

添加reserve:指针

V.reserve(10);

 

 

 

 

 

插入新项时就不用从新拷贝构造 b和c了,提升效率。code

 

   2. vector内存释放对象

《Effective STL》中“条款17”:使用“交换技巧”来修整过剩容量blog

当vector、string大量插入数据后,即便删除了大量数据(或者所有都删除,即clear) 并无改变容器的容量(capacity),因此仍然会占用着内存。 为了不这种状况,咱们应该想办法改变容器的容量使之尽量小的符合当前 数据所需(shrink to fit)内存

《Effective STL》给出的解决方案是:

即先建立一个临时拷贝与原先的vector一致,值得注意的是,此时的拷贝 其容量是尽量小的符合所需数据的。紧接着将该拷贝与原先的vector v进行 交换。好了此时,执行交换后,临时变量会被销毁,内存获得释放。此时的v即为原先 的临时拷贝,而交换后的临时拷贝则为容量很是大的vector(不过已经被销毁)

 

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    {
        vector<int> V;

        for(int i=0;i<1000000;i++)
        {V.push_back(i);}
        qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity();

        qDebug()<<"Clear:";
        V.clear();
        qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity();

        qDebug()<<"Swap(V):";
        vector<int>(V).swap(V);
        qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity();
    }
    return app.exec();
}

相关文章
相关标签/搜索