Как можно иметь массив строк в C ++? - PullRequest
3 голосов
/ 31 мая 2011

Когда вы обращаетесь к элементам массива с помощью array [i], я думал, что C ++ займет начальную позицию массива в памяти и добавит i * sizeof (один элемент массива), а затем разыменует этот адрес (или сделает что-то эквивалентное к тому, что я только что описал). Однако мне кажется, что если у вас есть массив строк (std :: string), каждый элемент может иметь разный размер в зависимости от количества символов в строке, поэтому должно происходить что-то еще.

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

Может кто-нибудь объяснить мне, как это работает?

Ответы [ 7 ]

5 голосов
/ 31 мая 2011

Размер строки постоянен, но он (на некотором уровне) имеет указатель на некоторые данные непостоянного размера.

Размер указателя постоянен, а размер указателя - нет.

4 голосов
/ 31 мая 2011

std::strings являются объектами. Размер одного std::string совпадает с размером другого std::string. Они косвенно «содержат» свои данные посредством динамического выделения, что не влияет на размер объекта-владельца.

Точно так же, если вы имеете в виду строки в стиле C, вы фактически пропускаете только char* (или pointers-to-char). Указатели всегда имеют одинаковый размер, независимо от длины блока памяти, на который они указывают.

2 голосов
/ 31 мая 2011

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

1 голос
/ 31 мая 2011

Строковый объект имеет размер, и он будет различаться в зависимости от того, какой компилятор реализации и т. Д. Вы правы в оценке того, кто c ++ обрабатывает массивы, но пропускает данные указателя.Строковый класс в своих недрах имеет указатель на некоторые данные кучи, которые могут иметь любой произвольный размер, но указатель на эти данные имеет фиксированный размер.Таким образом, внутри компоновки данных строки есть способ для компилятора создавать однородные объекты с нефиксированными данными представления.

1 голос
/ 31 мая 2011

Если вы ссылаетесь на тип C ++ std::string, каждый из элементов массива строк занимает одинаковое количество памяти. Однако каждая строка может содержать указатель, указывающий на другую позицию в памяти разной длины, где она фактически хранит строку.

Чтобы увидеть пример (пример кода), представьте класс std::string примерно так:

struct string
{
  size_t length;
  const char* data;
  // other members..
};

Обратите внимание, что размер структуры всегда один и тот же (size_t и указатель), но память, на которую указывает текущая строка, может отличаться.

0 голосов
/ 31 мая 2011

Вот как бы вы сделали это в коде ...

const int ARRSIZE = 5;
string arrayOfStr[ARRSIZE] = {"one", "two", "three"};

for (int i = 0; i < ARRSIZE; ++i)
{                 
    cout << arrayOfStr[i] << endl;                  
}
0 голосов
/ 31 мая 2011

Поскольку строка является символьным указателем, массив строк - это массив (char *) - смежный вектор (char *) указателей.Изменение строки приведет к изменению памяти, на которую указывает каждый элемент.Теперь, если вы объявили, что он статически распределен:

char foo[10][10];

, то с точки зрения разметки памяти он неотличим от

char foo2[100];

, и было бы возможно повредить память, написав послезаявленный размер;это одна из причин, по которой следует использовать std::string вместо строк в стиле C, что, возможно, является лучшим примером того, почему C является паршивым языком для программирования приложений.(Массив std::string будет массивом объектов, в каждом из которых будет храниться (char *), где вам не о чем беспокоиться - std::string сделает это за вас, и гораздо надежнее.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...