2016-08-29 4 views
-3

Я чтение 400mb файла в C вектор ++ со следующим кодом:C++ утечка памяти с STD :: векторами

#define RAMALLOC 20000000 
struct worddata { 
    std::string name; 
    double ussage; 
}; 
// ... 
int counter = 0; 
std::string dName; 
double dUssage; 
std::vector<worddata> primDataBank; 
primDataBank.resize(RAMALLOC); 
std::ifstream fIn(PATH + "output.dat"); 
while (fIn >> dName >> dUssage) { 
    primDataBank[counter].name = dName; 
    primDataBank[counter].ussage = dUssage; 
    counter++; 
} 

Я жил вектор к размеру 20,000,000 элементов, так как я назначить к нему в цикле использование плунжера не должно увеличиваться. Однако, когда я запускаю его, использование плунжера быстро растет.

В снимке кучи отладки Visual Studio, это показывает мне, что баран занят processFrequencyData.exe!std::_Container_proxy. «Выделение стека вызовов» выглядит так:

enter image description here

Это, как представляется, имеют свои корни в векторе.

Как я могу остановить использование барана от увеличения?

Спасибо.

Update:

Мой использование баран по-прежнему быстро растет, когда я закомментируйте строки кода в то время цикла, который присваивает значения

while (fIn >> dName >> dUssage) { 
    //primDataBank[counter].name = dName; 
    //primDataBank[counter].ussage = dUssage; 
    counter++; 
} 

Однако таран использование не увеличивается, когда я код комментария:

//std::vector<worddata> primDataBank; 
//primDataBank.resize(RAMALLOC); 
+2

Можете ли вы дать нам [mcve]? – jaggedSpire

+0

Вы можете сделать паузу в своей программе сразу после изменения размера вектора? Когда вы нажмете паузу, вы увидите, что память больше не выделена. –

+6

* Я разместил вектор размером до 20 000 000 элементов, так как я назначаю его в цикле, использование плунжера не должно увеличиваться. * Ну ... да, должно. Вначале ваш вектор содержит * пустые строки *, которые вы заполняете при выполнении цикла, те же берут память. – Borgleader

ответ

1

Вектор ваш Создание использует приблизительно

20000000 * 32 байт = 640 000 000 т.е. 640 МБ // который сказал 640К будет достаточно?

Размер слова данных происходит из std :: string составляет около 24 байтов + 8 для двойника.

Затем вы начинаете читать строки, если они достаточно малы, строка, возможно, использует мелкоструйную оптимизацию, которая использует внутренние данные и емкость для хранения символов. Но если они больше символов ~ 12 (???), строка выделяет дополнительный массив для сохранения символов.

Обновления требуют дополнительного изучения.

+0

Самая длинная строка, в которой я нуждаюсь, составляет 11 символов. Было бы очень полезно использовать только 640 КБ памяти, так как моя программа в настоящее время пытается использовать более 2 гб ... – FelisPhasma

+0

@FelisPhasma, ну с текстом 400 МБ вам понадобится достаточный объем памяти с вашей текущей структурой. Вы можете попробовать что-то еще для текста, например, пытается. – Surt

1

Использование вашей памяти увеличивается, потому что вы создаете и сохраняете все эти st которые вы читаете из файла.

Строка не является объектом фиксированного размера, поэтому единственным способом, которым вы можете предварительно выделить пространство для строк, является использование настраиваемого распределителя.

Вы должны предпочесть использование резерва и emplace_back, а не размер и настройки полей, как это позволит избежать выделения 0 длины строки вам не нужны.

Я нахожу ваше обновление трудно поверить.