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

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

 Anthony Williams22 сент. 2010 г., 17:23
Если sizeof возвращает количество битов в указателе, значит ваш компилятор не работает
 mkb22 сент. 2010 г., 17:23
@Queso: sizeof () возвращает байты, а не биты. 32-байтовый указатель - это 256-битный адрес
 Steve Jessop22 сент. 2010 г., 17:51
@Martin: потому что «влажность» в значительной степени определяется как свойство воды (или в любом случае жидкости). Я не знаю, что «32» определяется как размер строки.
 Martin York22 сент. 2010 г., 20:45
@ Стив Джессоп: спрашивать, почему ничего не значит; это так, потому что разработчики сделали это так. Сейчас спрашиваюwhy is string 32 bytes for compiler X version y on platform z running OS a revision b имеет смысл. Почему вода на STP мокрая на земле 1.0? Потому что в этой среде он находится в жидкой форме. Поэтому я называю это аналогией. Спрашивать, почему строка 32 так же бессмысленно, как спрашивать, почему вода мокрая. Обатолько правда при определенных условиях. Без понимания условий невозможно ответить.
 James McNellis22 сент. 2010 г., 17:22
Если вы откроете свою платформу<string> заголовок, вы можете понять, почему именноstd::string это размер. @Queso:sizeof дает размер объектав байтах.
 Martin York22 сент. 2010 г., 17:50
Почему вода мокрая?
 agam25 сент. 2010 г., 09:38
Да, имеет смысл ... мне подходит для того, чтобы относиться к StackOverflow как к Twitter.
 Martin York22 сент. 2010 г., 20:35
@ Стив Джессоп: Примечание. Все мы решили стать программистами, чтобы мы чувствовали себя БОГОМ (архитекторами нашей маленькой Вселенной).
 Martin York22 сент. 2010 г., 18:09
@ Steve Jessop: вода влажная из-за текущей реализации (земля как STP, которая позволяет воде быть жидкой). В других реализациях он не мокрый (как Юпитер, где это газ). Таким образом, эта строковая реализация равна 32, потому что так она была построена в этой реализации, и будет 16 в других реализациях и 64 в еще одной. Размер струны (например, вода) зависит от среды, в которой она используется.
 Steve Jessop22 сент. 2010 г., 18:28
Итак, вода является жидкой из-за земного STP, и мы могли бы продолжить бурение, посмотрев на факторы, которые на это влияют (например, на атмосферное давление влияют масса и выброс газа). Так что же спрашиватьЗачем один набор разработчиков выбрал 32, а другой выбрал 64, имеют отношение к запросуЗачем земля имеет определенное поверхностное давление и температуру? Один из них - выбор, сделанный разумным существом. Другой вариант - это не IMO, но даже если это и есть IYO, я не думаю, что разработчики C ++ вполне могут претендовать на невыразимость, которую делает Бог.

Ответы на вопрос(6)

Решение Вопроса

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

Кроме того, будет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 Большая тройка (GCC libstdc ++ начиная с версии 5, Clang libc ++ и реализация MSVC) все это делают. Другие тоже могут.

 Konrad Rudolph02 июн. 2016 г., 09:07
@ManuelSelva Точно.
 Manuel Selva02 июн. 2016 г., 08:58
@KonradRudolph очень маленькие строки сохраняются непосредственно в объекте, и это может быть стек или куча в зависимости от того, где расположена строка, не так ли?
 Konrad Rudolph02 окт. 2018 г., 11:02
@ LukeFisk-Lennon Вы не можете. Оптимизация небольших строк - это деталь реализации некоторых (ну, во всех современных) реализаций стандартной библиотеки, она не определяется языком. Таким образом, вы не можете изменить его в C ++. Вы также не можете изменить его вне C ++ (например, через параметры компилятора), потому что такое изменение будетЛомать ABI, Тем не менее, GCC4 не выполняет оптимизацию небольших строк, поэтому в принципе вы можете настроить свой GCC с--with-default-libstdcxx-abi=gcc4-compatible но это было бы ужасной идеей (= очень старая реализация).
 Luke Fisk-Lennon02 окт. 2018 г., 03:17
@KonradRudolph Как заставить строки всегда выделяться кучей? (Для намерения иметь строковые объекты размером менее 32 байтов, например, 8 байтов.)
 Luke Fisk-Lennon02 окт. 2018 г., 11:30
@KonradRudolph Хорошо, я вижу. Спасибо за быстрый ответ.

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

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

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

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

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

 Erik Aronesty16 мая 2017 г., 22:07
AWW ... нет ссылок? что случилось со складыванием?
 Martin York16 мая 2017 г., 23:48
@ErikAronesty Был этап, на котором пытались подсчитать ссылкиstd::string но стало очевидно, что его не очень эффективно (за несколько лет на нем было несколько работ), и вместо этого стала популярной оптимизация коротких строк.

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

 Theo21 июл. 2016 г., 18:40
Обратите внимание, что реализация IBM-AIX C ++ содержит небольшую строковую реализацию с буфером в 32 символа (см. Здесь:www-01.ibm.com/support/docview.wss?uid=swg21453760)
 Dennis Zickefoose22 сент. 2010 г., 18:30
Из того, что я понимаю, Dinkumware и STLPort оба делают, но реализация gcc - нет.
 Steve Jessop22 сент. 2010 г., 17:52
Где "как правило" == "на Windows" ;-)
 Anthony Williams22 сент. 2010 г., 18:06
Компиляторы Windows - не единственные, кто выполняет оптимизацию небольших строк
 Steve Jessop22 сент. 2010 г., 18:13
Конечно, но если вы не хотите называть их, то трудно судить, является ли это «типичным» поведением, или просто называют его на том основании, что это поведение обычной реализации (и, вероятно, других).
 Steve Jessop22 сент. 2010 г., 18:32
Кстати, я упоминаю об этом, потому что «обычно» охватывает диапазон от «я достаточно уверен, что вы больше ничего не увидите», до «50% или более реализаций, которые я использовал, делают это». Я думаю, это очень легко понять. Ни эту оптимизацию, ни ее отсутствие нельзя считать необычной.

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

но идея та же.

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

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

Ваш ответ на вопрос