выделение памяти для массива строк - PullRequest
1 голос
/ 06 октября 2011

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

Что происходит, когда я определяю массив следующим образом:

std::string array[] = {"abc", "defghi", "jk", "lmnop", "qrstuvwxyz"};?

Есть ли ограниченный объем памяти, выделенный для каждой строки?Или массив выделяется динамически?

Ответы [ 3 ]

3 голосов
/ 06 октября 2011

Не задумывайся о вещах. Когда вы говорите T x[N];, вы объявляете автоматический (то есть локальный) массив. Это очень похоже на объявление T x1;, T x2;, ..., T xN;. Экземпляр std::string всегда занимает один и тот же небольшой размер в контексте объявления (например, в стеке); только память, которой он управляет (по умолчанию в бесплатном хранилище), является динамической.

Обратите внимание, что когда вы пишете std::string s("Hello"); в своем коде, строковый литерал (который передается конструктору), конечно, где-то сохраняется в двоичном файле вашей программы и загружается в память программы (обычно для чтения только сегмент данных). Так что если вам действительно нужно прочитать эти строки (в отличие, скажем, изменить их), то вы можете просто объявить массив указателей на символы и сэкономить память:

const char * strings[] = { "Hello", "World", "!" };   // just one copy in r/o memory
2 голосов
/ 06 октября 2011

Литеральные строки хранятся в сегменте данных двоичного файла.

Редактировать:

Хороший момент в комментарии ildjarn.Std :: strings создаются конструктором копирования в массивах.Где они хранятся, зависит от реализации.Некоторые реализации хранят небольшие строки (менее 32 символов), встроенные в массив.Другие будут выделяться из std :: allocator, который обычно выделяется из кучи.

1 голос
/ 06 октября 2011

В этом случае компилятор помещает эти литералы в раздел .data вашего двоичного файла ELF.Поэтому в этом случае они статически размещаются в создаваемом исполняемом (или библиотечном) файле.

Раздел .data обычно зарезервирован для констант времени компиляции, которые не просто жестко запрограммированы в инструкциях по сборке.Как видите, гораздо дешевле просто сохранить адрес в строке, чем помещать его везде, где он используется (как это делают некоторые целые числа и определенные макросы).

...