Почему sizeof (строка) == 32? - PullRequest
       1

Почему sizeof (строка) == 32?

19 голосов
/ 22 сентября 2010

Какие издержки в строковой структуре приводят к тому, что sizeof () равно 32?

Ответы [ 6 ]

45 голосов
/ 22 сентября 2010

Большинство современных std::string реализаций 1 сохраняют очень маленькие строки непосредственно в стеке в массиве char статического размера вместо использования динамической памяти кучи. Это известно как Оптимизация небольших (или коротких) строк (SSO). Это позволяет реализациям избежать выделения кучи для небольших строковых объектов и улучшает локальность ссылок.

Кроме того, будет std::size_t элемент для сохранения размера строк и указатель на фактическое char хранилище.

Как это конкретно реализовано, отличается, но что-то вроде следующего работает:

template <typename T>
struct basic_string {
    char* begin_;
    size_t size_;
    union {
        size_t capacity_;
        char sso_buffer[16];
    };
};

На типичных архитектурах, где sizeof (void*) = 8, это дает нам общий размер 32 байта.


1 «Большая тройка» (libstdc ++ GCC начиная с версии 5, реализация Clang libc ++ и MSVC) - все это делает. Другие тоже могут.

11 голосов
/ 22 сентября 2010

std::string обычно содержит буфер для «оптимизации небольших строк» ​​- если строка меньше размера буфера, выделение кучи не требуется.

4 голосов
/ 22 сентября 2010

Мое предположение:

class vector
{
    char type;
    struct Heap
    {
      char*   start;
      char*   end;
      char*   allocatedEnd;
    };
    struct Stack
    {
      char    size;
      char    data[27];
    }
    union
    {
        Stack   stackVersion;
        Heap    heapVersion;
    } version;
};

Но могу поспорить, есть сотни способов сделать это.

3 голосов
/ 17 марта 2016

В g ++ 5.2 (например, в g ++ 4.9 он отличается) строка в основном определяется как:

class string {
  char* bufferp;
  size_t length;
  union {
    char local_buffer[16];
    size_t capacity;
  };
};

На обычном компьютере это составляет до 32 байтов (8 + 8 + 16).

Фактическое определение, конечно,

typedef basic_string<char> string;

но идея та же.

3 голосов
/ 22 сентября 2010

Это зависит от библиотеки. Вы не должны полагаться на размер std::string объектов, поскольку он может меняться в разных средах (очевидно, между разными поставщиками стандартных библиотек, но также между разными версиями одной и той же библиотеки).

Имейте в виду, что std::string реализации написаны людьми, которые оптимизировали для различных вариантов использования, как правило, приводят к 2 внутренним представлениям, одно для коротких строк (небольшой внутренний буфер) и одно для длинных строк (выделенных в куче) внешний буфер). Накладные расходы связаны с удержанием обоих в каждом std::string объекте.

1 голос
/ 22 сентября 2010

В: Почему собака желтая?A: Это не обязательно.

Размер объекта (an?) Std :: string зависит от реализации.Я только что проверил MS VC ++ 2010. Он действительно использует 32 байта для std :: string.Существует 16-байтовое объединение, которое содержит либо текст строки, если он уместится, либо указатель на кучное хранилище для более длинных строк.Если бы разработчики решили хранить 18-байтовые строки в строковом объекте, а не в куче, размер был бы 34 байта.Другие 16 байтов содержат служебные данные, содержащие такие вещи, как длина строки и объем памяти, выделенный в настоящее время для строки.

Другая реализация всегда может выделить память из кучи.Такая реализация, несомненно, потребует меньше памяти для строкового объекта.

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