Почему sizeof (string) == 32?

Что такое накладные расходы в строковой структуре, которая заставляет sizeof() быть 32?

Ответы

Ответ 1

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

Кроме того, будет существовать член std::size_t для сохранения размера строк и указателя (потенциально неиспользуемого, см. выше) для хранилища кучи.

Ответ 2

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

Ответ 3

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

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;
};

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

Ответ 4

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

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

Ответ 5

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

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

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

Ответ 6

В 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;

но идея одинаков.