Что заставляет вас думать, что вы потребляете 5 ГБ?
Вы создаете массив из 46657 vector<char*>
. Каждый вектор имеет в среднем 100 char*
, указывая на вновь выделенную строку размером 255 байтов. Это как минимум sizeof(buckets)+46657*100*(sizeof(char*)+255)
байтов. В зависимости от реализации, это может быть около 1,2 Гб. Векторы могут содержать некоторое пространство, зарезервированное для более быстрого роста. Но это принципиально не изменит наш порядок величины.
Все это огромно, возможно, больше, чем нужно, но это далеко от 5Gb, которые вы измеряете. Но что вы измерили в первую очередь?
Предоставляемая вами статистика использования памяти, скорее всего, управляется на уровне операционной системы. Это память, используемая процессом, выполняющим ваш код, а не обязательно код, который использует ваш код. Все это зависит от реализации, но в целом стандартная библиотека может выделять очень большие фрагменты памяти из ОС, поскольку вызовы в ОС обходятся дороже, чем локальные вызовы в пространстве пользователя. Этот большой кусок затем разрезается на части при каждом вызове new
или malloc
. Это похоже на оптового продавца и розничного продавца.
Чтобы узнать, сколько памяти занимает ваш код, вам нужно более точно отслеживать / профилировать память. Например, вы можете использовать valgrind
или другие инструменты в зависимости от вашей ОС.
Предотвращение утечек
Мы не видим полный код, поэтому утечки также не исключаются. Поскольку вы вручную управляете memroy, риск утечки выше. Не говоря уже о неанизированном сканировании, которое может превышать 255 выделенных символов и поврежденную память.
Таким образом, более безопасный подход может быть следующим:
vector<string> buckets[46657];
...
for ...
string temp; // let the string take care of its own memory
getline(cin, temp);
...
В качестве побочного эффекта вы также получаете выгоду от оптимизированного управления памятью, если у вас много небольших строк.