Как удалить элементы в векторе.(стереть не получится) - PullRequest
2 голосов
/ 15 февраля 2012

Когда я удаляю элементы в векторе с помощью «стирания», память не очищается.Например, я делаю вектор размером 2000. После создания программа использует 1,5 МБ памяти.Когда я сделаю вызов стирания, ничего не будет очищено.Все элементы ушли.Но они все еще находятся в памяти.

Например:

#include <iostream>
#include <vector>

using namespace std;


int main()
{
    //Makes a vector of 2000 items
    vector<int> test(200000);

    //Pause for test purpose
    system("pause");

    //erase all elements
    test.erase(test.begin(),test.end());

    //Pause for test purpose
    system("pause");

    return false;
}

Размер возвращает 0. Но процесс все еще использует 1,5 МБ памяти.

Ответы [ 4 ]

11 голосов
/ 15 февраля 2012

Процесс хранит память по двум причинам:

  • std::vector перераспределяет память только тогда, когда она увеличивается, а не когда она уменьшается.
  • Освобожденная память часто сохраняется процессом для повторного использования.

В C ++ 11 векторы имеют функцию-член shrink_to_fit, которая попросит вектор уменьшить объем выделенной памяти, если это возможно. Там нет гарантии, что это сделает это, хотя. В C ++ 03 или если вы хотите гарантировать освобождение избыточной памяти, вы можете использовать хитрость замены вектора на вновь выделенный:

std::vector<int>(test).swap(test);

или если вы хотите полностью очистить его:

std::vector<int>().swap(test);

Этот трюк переносит владение выделенной памятью во временный вектор; в конце выражения этот вектор уничтожается, освобождая память.

Независимо от того, была ли освобождена память из процесса, полностью зависит от того, как ваша библиотека управляет бесплатным хранилищем. Часто небольшие выделения (возможно, до нескольких мегабайт) обрабатываются кучей - процесс запрашивает из системы большие блоки памяти и разбивает их на маленькие части. Блоки не могут быть освобождены, пока не будут освобождены все маленькие части, и многие реализации не освободят их даже тогда.

Большие выделения могут быть запрошены непосредственно из системы, и в этом случае они будут освобождены после освобождения.

Таким образом, вы можете получить ожидаемый эффект с помощью такого кода:

// A few gigabytes will probably be allocated directly.
// You'll have to reduce this on a 32-bit system, or if there's not enough memory
std::vector<int> test(1000000000)

// Use the "swap trick" to ensure the memory is deallocated.
std::vector<int>().swap(test);

Но нет никакой гарантии, что даже это освободит память от процесса; детали выделения памяти не определены стандартом и зависят от реализации компилятора / библиотеки.

8 голосов
/ 15 февраля 2012

erase не освобождает память.После кода, о котором идет речь test.capacity() >= 200000 требуется стандарт.Используйте

test.shrink_to_fit(); // in C++11
vector<int>(test).swap(test); // in C++03

, чтобы уменьшить емкость вектора.Обратите внимание, что это все еще не гарантирует, что использование памяти, как замечено остальной частью системы, уменьшится.Куча процесса не может быть уменьшена в размере в целом.

0 голосов
/ 15 февраля 2012

Когда процесс завершается, память освобождается в вашем случае. Таким образом, нет необходимости стирать вектор.
Если вы хотите продолжать использовать вектор в цикле, рассмотрите возможность использования clear(), который очищает содержимое вектора.
Если вектор используется в объекте, то после уничтожения объекта вектор также уничтожается.
Но если вектор содержит указатели, вы должны явно удалить их.

0 голосов
/ 15 февраля 2012

Вы можете проверить это следующим образом:

int main() 
{ 
    //Makes a vector of 2000 items 
    {
        vector<int> test(200000); 

       //Pause for test purpose 
       system("pause"); 

       //erase all elements 
       test.erase(test.begin(),test.end()); 

       // Call erase or not, but destructor will be called here - freeing all memory
    } 

    //Pause for test purpose 
    system("pause"); 

    return false; 
} 

vector.erase не освобождает память для простых целей - возможно, повторное использование выделенной памяти, а не перераспределение для будущих запросов.

...