Я очень часто видел итерации массива с использованием простой арифметики указателей даже в более новом коде C ++. Интересно, насколько они безопасны на самом деле, и стоит ли их использовать. Рассмотрим этот фрагмент (он также компилируется в C, если вы calloc
на месте new
):
int8_t *buffer = new int8_t[16];
for (int8_t *p = buffer; p < buffer + 16; p++) {
...
}
Не приведет ли этот тип итерации к переполнению и пропаданию цикла полностью, когда buffer
происходит выделяться по адресу 0xFFFFFFF0
(в 32-битном адресном пространстве) или 0xFFFFFFFFFFFFFFF0
(64 бит)?
Насколько я знаю, это будет исключительно неудачное, но все же возможное обстоятельство.
Это безопасно. Стандарты C и C ++ явно позволяют вычислять значение указателя, которое указывает один элемент за концом массива, и сравнивать указатель, который указывает в массиве, с этим значением.
Реализация, которая имела проблему переполнения в описываемой вами ситуации, просто не имела бы права помещать массив прямо в конец памяти, как этот.
На практике более вероятная проблема buffer + 16
Сравнение равно NULL
, но это также не допускается, и соответствующая реализация должна оставить пустое место после конца массива.
Других решений пока нет …