Подтвердить что ты не робот

У max_size() из std::vector <char> есть ошибка?

Я озадачен результатом std::vector< char >::max_size() в системе n= 32 и n= 64 бит, которые я тестировал. Результат равен 2 n & minus; 1. Позвольте мне объяснить, почему я озадачен.

Каждая реализация std::vector<T>, о которой я знаю, имеет три члена типа T*: begin_, end_, capacity_.

begin_ указывает на первое значение вектора, а end_ указывает на значение после последнего. Поэтому размер вектора определяется выражением end_ - begin_. Но результатом этого различия является тип std::ptrdiff_t, который является знаковым числом из n бит для каждой реализации, о которой я знаю.

Поэтому этот тип не может хранить 2 n & minus; 1, но только до 2 n & minus; 1 & минус; 1. Если вы посмотрите на свою реализацию std::vector, вы ясно увидите, что размер имеет разницу в 2 указателя (перед тем как передать его в целое число без знака).

Итак, почему они могут притворяться, что хранят больше 2 n & minus; 1 без разбиения .size()?

4b9b3361

Ответ 1

Это, очевидно, ошибка в некоторых стандартных реализациях библиотек. Я сделал больше работ по этому вопросу и, используя следующий код

#include <iostream>
#include <climits>
#include <vector>

int main() {
    auto v = std::vector<char>();
    std::cout << "Maximum size of a std::vector<char>: " <<
            v.max_size() << std::endl;
    std::cout << "Maximum value a std::size_t can hold: " <<
            SIZE_MAX << std::endl;
    std::cout << "Maximum value a std::ptrdiff_t can hold: " <<
            PTRDIFF_MAX << std::endl;

    return 0;
}

нетрудно показать, что:

  • в libС++, используемый clang, max_size() возвращает PTRDIFF_MAX
  • в libstdС++, используемом gcc 4.9.2, max_size() возвращает SIZE_MAX
  • в реализации Visual Studio 2013 max_size() возвращает SIZE_MAX

Следовательно, libstdС++ и реализация стандартной библиотеки Microsoft имеют ошибку, но libС++ ее не имеет. Я напишу отчет об ошибках в отношении этих 2.

  • Gcc. Сообщается как ошибка 65131. Он отклонен, поскольку ABI говорит, что для всех 32-битных ABI вы не можете выделить более половины адресного пространства. Эта проблема была ранее рассмотрена здесь: https://gcc.gnu.org/ml/gcc/2011-08/msg00221.html