vector的內存分配與釋放


  1. vector內存分配

《Effective STL》中“條款14”:使用reserve來避免不必要的重新分配

關於STL容器,最神奇的事情之一是只要不超過它們的最大大小,它們就可以自動增長到足以容納你放進去的數據。(要知道這個最大值,只要調用名叫max_size的成員函數。)對於vector和string,只要需要更多空間,就以realloc等價的思想來增長。這個類似於realloc的操作有四個部分:

  1. 分配新的內存塊,它有容器目前容量的幾倍。在大部分實現中,vector和string的容量每次以2為因數增長。也就是說,當容器必須擴展時,它們的容量每次翻倍。
  2. 把所有元素從容器的舊內存拷貝到它的新內存。
  3. 銷毀舊內存中的對象。
  4. 回收舊內存。

給了所有的分配,回收,拷貝和析構,你就應該知道那些步驟都很昂貴。當然,你不會想要比必須的更為頻繁地執行它們。如果這沒有給你打擊,那么也許當你想到每次這些步驟發生時,所有指向vector或string中的迭代器、指針和引用都會失效時,它會給你打擊的。這意味着簡單地把一個元素插入vector或string的動作也可能因為需要更新其他使用了指向vector或string中的迭代器、指針或引用的數據結構而膨脹。

 DEMO

#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了,提高效率。

 

   2. vector內存釋放

《Effective STL》中“條款17”:使用“交換技巧”來修整過剩容量

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM