Почему 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;
но идея одинаков.