Имеют ли файл, содержащий слова, разделенные символом новой строки, и вектор строк для этих слов в C ++, одинакового размера? - PullRequest
0 голосов
/ 29 июня 2018

Файл имеет следующую форму:

word1
word2
word3
...

И я создаю вектор строк после чтения этих слов из файла следующим образом:

std::vector<string> words;
string w;
ifstream file("input");
while(getline(file,w))
    words.push_back(w);
file.close();

Будет ли размер физической памяти, занимаемой вектором, таким же, как размер входного файла? Почему?

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Будет ли размер физической памяти, занимаемой вектором, таким же, как размер входного файла?

Это зависит от того, что вы подразумеваете под «размером физической памяти, занимаемой вектором» . Размер самого векторного объекта обычно равен 3 указателям (или 1 указателю и 2 числам), таким как 24 байта в 64-разрядной архитектуре. Однако вектор динамически выделяет пространство для как минимум N строковых объектов, где N - количество строк файла. Обратите внимание, что если вы не зарезервируете векторное пространство, он, вероятно, выделит больше места, чем для N строк.

Каждый строковый объект снова имеет некоторый «внутренний» размер (24 байта с libc ++ / Clang, 32 байта с libstdc ++ / GCC в моих экспериментах).

И затем каждая строка должна хранить текстовую строку. Он может выделять память динамически или для короткой строки может использовать оптимизация маленькой строки . При динамическом распределении памяти необходимо учитывать некоторые отступы, поскольку динамически распределенные буферы выровнены (в моей среде до 16 байт).

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


Если вы хотите избежать этих издержек, просто прочитайте все содержимое файла в один массив символов (вектор, строку), а затем создайте дополнительный массив с указателями на то, где начинаются отдельные строки.

0 голосов
/ 29 июня 2018

Векторная реализация имеет два следа памяти: sizeof(vector) - это память, используемая в стеке (обычно 24 байта), а затем память выделяется динамически, сначала с помощью vector, а затем с помощью аргументов string .

Вектор вполне может выделить больше памяти, чем ему нужно для хранения всех строк: если вы увеличите его на push_back (или emplace_back), он удваивает динамически выделяемую память всякий раз, когда ему не хватает места.

Строки, наконец, имеют свои собственные издержки: для коротких слов (короче sizeof(string)) неиспользуемая память в строке тратится впустую, в то время как для длинных слов строка должна выделять динамическую память и сохранять отдельный указатель (вызывая перегрузку памяти) .

Таким образом, ответ таков: NO , vector<string> занимает больше места (которое может быть распределено между стеком и различными местами в куче).

...