C вектор указателя на объект — max_size()

#c #vector #max-size

#c #вектор #максимальный размер

Вопрос:

У меня есть класс яблоки

 class apples
{
  private:
      double x;
      double y;
      double z;
  public:
      //some methods
};
  

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

 int _tmain(int argc, _TCHAR* argv[])
{
vector<apples *> myvector;
cout<<"max :"<<myvector.max_size();
return 0;
}
  

это дало мне:

 1073741823
  

теперь мой вопрос заключается в том, могу ли я действительно хранить 1073741823 указателей в этом векторе или это ограничение памяти (т.Е. 1073741823 байт) вектора?

итак, если есть 2 вектора

 vector<int> A
amp; 
vector<double> B
  

может ли A иметь 1073741823 элемента, а B также иметь 1073741823 элемента?
я прошу это уточнить, что
максимальное количество элементов, которые может хранить вектор, не зависит от типа объекта (int или double), который хранится?

(это не имеет никакого отношения к текущей емкости вектора!)
Кроме того, каким будет размер указателя на объект apple (не запрашивая размер объекта apple!)?
Спасибо.

Ответ №1:

Это ограничение библиотеки для хранения элементов в векторе.

vector::max_size() :

Возвращает максимальное количество элементов, которые может содержать векторный контейнер.

Это не объем дискового пространства, выделенного в настоящее время вектору (это можно получить с помощью member vector::capacity ), а максимальный потенциальный размер, которого может достичь вектор из-за ограничений реализации системы или библиотеки.

Таким образом, вы не можете хранить больше, чем это (и на практике, возможно, меньше, чем это из-за системных ограничений)

Другими словами, даже если у вас наилучшие ресурсы (память, процессор, …) и ваши элементы имеют минимальный размер, вы не можете хранить более max_size()

И согласно комментарию max_size() в заголовочном файле: Возвращает размер максимально возможного вектора%.

Комментарии:

1. значит ли это, что vector<int> или vector<double> может содержать 1073741823 элемента, несмотря на разницу в размере памяти int amp; double ?

2. Если у вас достаточно памяти, да. но, vector<double> выделит памяти больше vector<int> .

Ответ №2:

max_size возвращает верхнюю границу количества элементов, которые может содержать вектор. Это не означает, что v.resize(v.max_size()) это будет успешным. Это просто означает, что v.resize(v.max_size() 1) произойдет сбой.

Комментарии:

1. При условии, что v.max_size() 1 это не переполняется, конечно. (Переполнение приведет к неопределенному поведению перед вызовом v.resize() .)

2. @James Kanze, верно 🙂 Однако UB не 1 будет повышен unsigned int , и переполнение приведет к 0u . (Если, конечно, size_t не определено как unsigned char или unsigned short .)

3. @avakar я отредактировал вопрос. не могли бы вы взглянуть?

4. @avakar Нет неопределенного поведения для добавления, нет. Просто еще один пример того, почему использование size_t everywhere в стандартной библиотеке было плохим решением. (В любом случае, конечно, вы не получите сообщение об ошибке resize , но вектор не будет иметь нужного вам размера.)

Ответ №3:

Кроме того, каким будет размер указателя на объект apple (не запрашивая размер объекта apple!)?

Я уверен, что какой-нибудь языковой юрист придет и укажет, что это неверно, но на практике: 32-битные сборки будут использовать 32-битные указатели, поэтому указатель на объект равен четырем байтам. В 64-битных сборках вы получаете восемь байт на указатель.

Ответ №4:

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

Объем, который вы можете фактически сохранить, обычно существенно ниже из-за ограничений памяти.

Текущая емкость может быть найдена путем вызова vector::capacity() , и если вы хотите узнать, как далеко вы можете растянуть вектор в вашей текущей настройке, продолжайте изменять размер вектора до bad_alloc тех пор, пока не будет выдано исключение)

Ответ №5:

могу ли я действительно хранить 1073741823 указателей в этом векторе или это объем памяти вектора?

max_size() сообщает вам, что эта реализация vector не может обрабатывать размер больше этого; векторы до этого размера возможны, если для их хранения достаточно памяти.

зависит ли максимальное количество объектов, которые могут храниться в векторе, от типа объекта? если да, то как это вычислить?

Это зависит от реализации обоих vector и используемого распределителя. На практике это обычно происходит; вы, вероятно, обнаружите, что это равно чему-то вроде numeric_limits<size_t>::max() / sizeof (value_type) ; максимальное количество байтов, которое может быть выделено в массиве, деленное на размер объекта.

Кроме того, каким будет размер указателя на объект apple (не запрашивая размер объекта apple!)?

Это зависит от вашей платформы. Поскольку max_size() он такой маленький, я предполагаю, что вы используете 32-разрядную платформу, и в этом случае указатель будет 32 бита (4 байта). Другие платформы будут иметь разные размеры указателя.

Ответ №6:

hex(1073741823) = ‘0x3fffffff’

Так что это выглядит как некоторый заранее определенный предел.

Комментарии:

1. @CAD_coding Я думаю, что другие ответы достаточно подробно описали это — в основном это теоретический максимум, которого на практике вы никогда не сможете достичь из-за ограничений памяти.

2. Я попытался добавить более миллиарда элементов в vector<uint64_t> today на x64 Ubuntu на машине, которую я построил несколько лет назад (у нее 12 ГБ оперативной памяти). Не займет много времени, чтобы заполнить его.