Вот мое дикое предположение:
Во многих реализациях распределитель помещает некоторые метаданные рядом с выделенной областью.
(Например, размервыделение.) Таким образом, вы, по сути, выделяете больше, чем просили.
Давайте предположим, что size_t
- это 32-разрядный код.Скомпилировано для 32-бит.
Когда вы делаете:
int *array = new int[-1];
-1
становится -1 * 4 bytes = 4294967292
(после переполнения).Но если реализация распределителя помещает 4 байта метаданных рядом с выделенной областью.Фактический размер становится следующим:
4294967292 + 4 bytes = 0 bytes (after overflow)
Таким образом, фактически выделяется 0
байт.
Когда вы пытаетесь получить доступ к памяти, у вас возникает ошибка, так как вы выходите за пределынемедленно.
Теперь предположим, что вы делаете:
int *array = new int[-2];
-2
становится -2 * 4 bytes = 4294967288
(после переполнения).Добавьте 4 байта метаданных, и вы получите 4294967288 + 4 = 4294967292
.
Когда распределитель запрашивает 4294967292
байтов от ОС, он отклоняется.Таким образом, он выдает bad_alloc
.
Таким образом, в принципе, возможно, что -1
и -2
имеют значение между тем, будет ли он переполняться после того, как распределитель добавит свои метаданные.