Быстрый ответ почему вектор может привести к сбою и не Deque в том, что, так как вектор использует смежный буфер, вы будете bad_alloc «быстрее». А также по запросу, который просит большой кусок.
Почему? Поскольку менее вероятно, что вы сможете выделить смежный буфер, чем меньший.
vector
выделит определенную сумму, а затем попробует большой «realloc» для большего буфера. Возможно, возможно расширить текущее пространство памяти, но это может не произойти, и может потребоваться найти совершенно новый кусок памяти.
Предположим, что он будет расширяться в 1,5 раза. Таким образом, в настоящее время у вас есть 40% доступной памяти в используемом вами векторе, и ему нужно найти 60% доступной памяти, но не может сделать это в текущем местоположении. Хорошо, что доводит вас до предела, поэтому он не работает с bad_alloc
, но на самом деле вы используете только 40% памяти.
Таким образом, на самом деле имеется доступная память, и те операционные системы, которые используют «оптимистичное» распределение памяти, не будут случайно перенаправлены для вас. Вы много просили, и это не могло дать вам. (Они не всегда полностью оптимистичны).
deque
С другой стороны, запрашивает кусок за раз. Вы действительно будете использовать свою память, и в результате ее лучше использовать для больших коллекций, однако имеет недостаток, что, когда у вас заканчивается память, вы действительно заканчиваете работу. И ваш прекрасный оптимистичный распределитель памяти не может справиться с этим, и ваш процесс умирает. (Он убивает что-то, чтобы сделать больше памяти. К сожалению, это было ваше).
Теперь для вашего решения, как этого избежать? Ваш ответ может быть настраиваемым распределителем, то есть вторым параметром deque, который может проверить доступную реальную системную память и отказаться от выделения, если вы нажмете определенный порог.
Конечно, это зависит от системы, но вы можете иметь разные версии для разных машин.
Вы также можете установить свой произвольный «предел», конечно.
Предполагая, что ваша система Linux, вы можете быть в состоянии превратить overcommit прочь с
'echo 2 > /proc/sys/vm/overcommit_memory'
Вам понадобится корень (администратора) разрешения, чтобы сделать это. (Или получить кого-то, у кого есть это, чтобы настроить его таким образом).
В противном случае другие способы изучения использования памяти доступны в руководствах по Linux, обычно упоминаемых в /proc
.
Если ваша система не является Linux, а другая, которая перекомбинирована, вам придется искать, как вы можете ее обойти, написав свой собственный менеджер памяти. В противном случае возьмите более простой вариант произвольного настраиваемого максимального размера.
Помните, что с deque
ваш распределитель вызывается только тогда, когда вам нужно выделить новый «кусок», а не для каждого push_back
.
Я думаю, что это намеренно - он хочет получить bad_alloc. Он просто хочет поймать ошибку – chrisb2244
Какая причина аварии с deque? Вы пытались использовать отладчик? – kraskevich
См. [This] (http://ideone.com/3c5VL9) – P0W