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();
}

相關文章
相關標籤/搜索