При использовании std::vector::push_back для вставки неизвестного количества элементов следует ли проверять std::vector::max_size при каждом нажатии?

Я использую std::vector в контексте, когда некоторое неизвестное количество элементов вставляется по одному. std::length_error генерируется, когда std::vector::reserve превысит максимальный размер, но для std::vector::push_back такой гарантии нет. Мой первый инстинкт — проверять, выполняется ли my_vector.size() == my_vector.max_size() при каждом нажатии, и выдавать исключение, если максимум будет превышен.

Если я не сделаю такую ​​проверку, возможно ли, что контейнер молча войдет в недопустимое состояние? Например, может ли размер переполниться?

Спасибо!

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
401
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Нет. push_back() выкинет, если не сможет выделить память.

max_size() — теоретический предел. Я никогда не видел, чтобы это использовалось. Возможно, в контексте с крайне ограниченной памятью и отсутствием поддержки исключений это может быть полезно, но в целом нет.

std::vector сам по себе не генерирует исключение для push_back, а Allocate::allocator выдает исключение, когда вы превышаете максимальный предел.

Из https://en.cppreference.com/w/cpp/container/vector/push_back:

If an exception is thrown (which can be due to Allocator::allocate() or element copy/move constructor/assignment), this function has no effect (strong exception guarantee).

...

Some implementations also throw std::length_error when push_back causes a reallocation that would exceed max_size, due to implicitly calling an equivalent of reserve(size()+1).

std::vector::max_size вернуть постоянное число. Как правило, это размер 8 байт. целое число, размер вектора которого никогда не достигнет этого предела, если вы запустите свой код на обычной платформе, такой как ПК (поскольку значение целого числа размером 8 байтов очень велико, оно намного больше, чем размер физической памяти вашей машины + размер жесткого диска ), поэтому my_vector.size() == my_vector.max_size() никогда не будет правдой. Как правило, вам не нужно беспокоиться об отчете контейнера STL, он не может выделить достаточно памяти, когда код запускается на обычном компьютере.

Только на некоторых встроенных платформах (с очень ограниченной памятью) std::vector::max_size может быть маленьким. Даже на такой платформе значение max_size по-прежнему намного больше, чем физическая память, которую вы можете использовать. Вам нужно тщательно спроектировать свой код, который не позволит этому случиться, потому что, если это произойдет, вы ничего не сможете с этим поделать.

Представьте себе это:

try {
// this logical must be done, if not, the business logical will fail
vector.push_back(data); 
}catch(const std::exception& e) {
// program will not terminated, but what fail is fail, codes wrote here can not repair the failure. 
// The only thing you can do is report the condition to user: "sorry, your request failed"
}

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

Другие вопросы по теме