2015-10-16 2 views
3

Я пытаюсь узнать больше о том, как память обрабатывается на C++, и у меня возникает вопрос о том, как освобождается память при переназначении переменной. Чтобы контролировать потребление памяти, у меня есть (для Linux) функция CheckMem(), которая вызывает pmap, чтобы узнать, сколько памяти использует этот процесс. Затем я просто создаю вектор размером 1, переадресую его на вектор размером один миллион, затем переназначим его до размера 1 и наблюдаем, как изменяется память.C++ 11 релиз памяти в переменной переназначения

#include <iostream> 
#include <vector> 
#include <sstream> 
#include <cstdio> 
#include <unistd.h> 

using namespace std; 

void CheckMem() 
{ 
    char cmdstring[100],outbuf[500],buf[100]; 
    sprintf(cmdstring,"pmap -x %d | tail -1",getpid()); 
    FILE* output = popen(cmdstring,"r"); 
    fgets(outbuf,500,output); 
    size_t kb,rss,dirty; 
    istringstream ss(outbuf); 
    ss >> cmdstring >> buf >> kb >> rss >> dirty; 
    cout << "RSS: " << rss << " KB" << endl; 
} 

int main() 
{ 
vector<double> vd(1); 
CheckMem(); 
vd = vector<double>(1000000); 
CheckMem(); 
vd = vector<double>(1); 
CheckMem(); 
return 0; 
} 

Если я компилирую с г ++ (GCC версии 4.8.4), я получаю следующий результат:

RSS: 1184 KB 
RSS: 9128 KB 
RSS: 9136 KB 

Оказывается, что память используется для большого вектора (1 миллион двойники ~ 8 МБ) не выделяется, когда вектор переназначается размера 1. Однако, если я компилировать с флагом -std=c++11, тогда выходные изменения:

RSS: 1180 KB 
RSS: 9112 KB 
RSS: 1300 KB 

Теперь Appe памяти ars, которые будут выпущены путем переназначения. Стандарт C++ 11 каким-то образом обрабатывает память по-разному для переназначений?

ответ

3

Более чем вероятно, что разработчики библиотеки повторно используют емкость вектора, если она больше, чем емкость вектора, которую вы назначаете ему. Таким образом, они сохраняют распределение памяти.

Начиная с C++ 11 у нас есть назначение перемещения, поэтому, когда вы компилируете с помощью -std=c++11 вместо повторного использования емкости, временный вектор перемещается в существующий вектор, а содержимое исходного вектора перемещается во временный. В конце выражения временное уничтожается, и теперь у вас есть вектор с меньшей емкостью.

Если вы хотите, чтобы уменьшить емкость вектора, вы должны проверить: reduce the capacity of an stl vector

+0

Да. Кажется, это то, что происходит. Если я добавлю 'vector (0) .swap (vd)', тогда память будет выпущена в обоих случаях. – ragnar

+0

Цитата, указывающая, где она заявляет, или подразумевает, что назначенный вектору повторное использование привязанного к векторам хранилища будет полезным. В прошлый раз, когда я посмотрел, я подумал, что это не указано, но я, возможно, помню неправильно. – Yakk

+0

@Yakk Я сказал * Скорее всего, чтобы покрыть это, возможно, это не проблема, но это может быть. Должен ли я уточнить это больше? – NathanOliver

0

Разница заключается в движение приписывать, который был введен в C++ 11. До этого у вас был только конструктор копий, который скопировал бы вам новый вектор в старый вектор, если емкость достаточно велика.

С C++ 11 и перемещение присваивает данные нового вектора заменяет старые, которые затем уничтожаются.

Смежные вопросы