Максимальная длина строки std :: basic_string <_CharT> - PullRequest
2 голосов
/ 19 марта 2010

Мне было интересно, как можно исправить верхний предел длины строки (в C ++) для данной платформы.

Я изучил множество библиотек, и большинство из них определяют это произвольно. GNU C ++ STL (с экспериментальными функциями C ++ 0x) вполне определен:

size_t npos = size_t(-1); /*!< The maximum value that can be stored in a variable of type size_t */
size_t _S_max_len = ((npos - sizeof(_Rep_base))/sizeof(_CharT) - 1) / 4; /*!< Where _CharT is a template parameter; _Rep_base is a structure which encapsulates the allocated memory */

Вот как я понимаю формулу:

  • Тип size_t должен содержать количество единиц, выделенных для строки (где каждая единица имеет тип _CharT)
  • Теоретически, максимальное значение, которое может принимать переменная типа size_t, - это общее количество единиц 1 байта (т. Е. Типа char), которое может быть выделено
  • Предыдущее значение минус накладные расходы, необходимые для отслеживания выделенной памяти (_Rep_base), является, следовательно, максимальным числом блоков в строке. Разделите это значение на sizeof (_CharT), поскольку для _CharT может потребоваться больше байта
  • Вычтите 1 из предыдущего значения, чтобы учесть завершающий символ
  • Наконец, это оставляет деление на 4. Я понятия не имею, почему!

Я искал объяснения во многих местах, но нигде не нашел удовлетворительного (вот почему я пытался что-то придумать для этого! Пожалуйста, поправьте меня, если я ошибаюсь !!).

Ответы [ 4 ]

2 голосов
/ 06 апреля 2010

Комментарии в файле basic_string.h из GCC 4.3.4:

    // The maximum number of individual char_type elements of an
    // individual string is determined by _S_max_size. This is the
    // value that will be returned by max_size().  (Whereas npos
    // is the maximum number of bytes the allocator can allocate.)
    // If one was to divvy up the theoretical largest size string,
    // with a terminating character and m _CharT elements, it'd
    // look like this:
    // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
    // Solving for m:
    // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
    // In addition, this implementation quarters this amount.

В частности, обратите внимание на последнюю строку, «Кроме того, эта реализация делит эту сумму на четверти». Я понимаю, что это означает, что деление на четыре на самом деле совершенно произвольно .

Я попытался найти дополнительную информацию в журнале регистрации для basic_string.h , но он восходит только к 5 октября 2000 года, и этот комментарий уже присутствовал, как показано в этой ревизии, и я ' Я недостаточно знаком с этой кодовой базой, чтобы знать, где файл мог находиться в дереве исходных текстов до того, как был перемещен в его текущее местоположение.

0 голосов
/ 19 марта 2010

Если вы не возражаете против проверки во время выполнения, вы можете вызвать std::string::max_size, который возвращает максимально возможную длину строки. Это не даст вам никаких причин для его результата (и я не знаю, для чего /4 в коде GNU, я боюсь), но это, по крайней мере, даст вам что-то определенное для работы.

Это не статическая функция, хотя определение правильного значения для каждой строки может потребовать некоторой осторожности и / или небольшого количества системного кода. (Например, строка VC ++ для своей информации отсылается к своему распределителю. Это означает, что разные строки могут иметь разные максимальные размеры, если они используют разные распределители, я полагаю.)

0 голосов
/ 19 марта 2010

Практический предел, вероятно, будет намного меньше, чем абсолютный предел. Например, выделение памяти не удастся. Практические пределы не могут быть известны заранее.

0 голосов
/ 19 марта 2010

Вы можете создать небольшой класс-оболочку, содержащий std::string. Выставьте функции интерфейса, которые вам небезразличны. Если какой-либо вызов функции увеличит вашу строку сверх желаемой максимальной длины, вы можете вызвать исключение или иным образом вызвать ошибку.

Это предназначено для того, чтобы достичь цели (зафиксировать максимальную длину в строке), не вдаваясь в беспорядок расшифровки стандартной реализации библиотеки.

...