Проблема с освобождением памяти для нединамически созданных std :: vectors, хранящих нормальные (то есть нединамически распределяемые) данные - PullRequest
1 голос
/ 28 сентября 2011

Рассмотрим следующий код, скомпилированный с g++ problem.cpp -o problem:

#include <vector>

using namespace std;

int main()
{
    while(1){}
    return 0;
}

Когда этот код выполняется, команда top сообщает, что используется ~ 80 КБ памяти.

Теперь рассмотрим этот код:

#include <vector>

using namespace std;

int main()
{
    vector<int> testVec;
    for(int i = 0;i<100000000;i++)testVec.push_back(i);
    while(1){}
    return 0;
}

Как и ожидалось, в верхнем отчете говорится, что используется около 300 МБ памяти.

Теперь, наконец, рассмотрим этот код:

#include <vector>

using namespace std;

int main()
{
    vector<int> testVec;
    for(int i = 0;i<100000000;i++)testVec.push_back(i);
    testVec.clear();
    vector<int>().swap(testVec);
    while(1){}
    return 0;
}

Теперь top сообщает, что потребляется ~ 4196K (!) - почему не только ~ 80K, как в первом примере? Как я могу наконец освободить этот последний бит памяти, который предположительно используется вектором? Я читал, что в дополнение к .clear(), «трюк со свопом» предназначен для освобождения всего, но, очевидно, он не работает так, как я ожидал. Чего мне не хватает?

Ответы [ 3 ]

3 голосов
/ 28 сентября 2011

Возможно, вам следует просто игнорировать это. Трюк swap освобождает память от вектора, но это не означает, что распределитель (или даже malloc или эквивалентная реализация ниже) вернет память системе. То есть вектор, скорее всего, не тот, который удерживает память.

0 голосов
/ 28 сентября 2011

Не думаете ли вы об использовании std :: deque вместо этого? Он имеет другую политику выделения памяти и имеет возможность уменьшить выделенную память. Конечно, вы получите некоторую нехватку производительности при использовании больших наборов данных.

0 голосов
/ 28 сентября 2011

Из того, что я знаю, есть два способа освободить память в этом случае:

  1. Поместите код, который использует вектор, в скобки (простой и эффективный)

    {
       // ..........
    } 
    
  2. Используйте общий указатель, но убедитесь, что существует только один общий указатель.Вы можете вызвать «сброс», чтобы освободить память.

    shared_ptr<vector<int> > testVec(new vector<int>);
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...