Как использование массивов в C++ приводит к проблемам с безопасностью
Мне сказали, что оптимальный способ программирования на C++ - это использовать STL и строки, а не массивы и символьные массивы.
т.е.
vector<int> myInt;
скорее, чем
int myInt[20]
Тем не менее, я не понимаю, почему это может привести к проблемам с безопасностью.
5 ответов
Тогда я предлагаю вам прочитать о переполнении буфера. Гораздо более вероятно, что программист создает или рискует переполнение буфера при использовании необработанных массивов, поскольку они дают вам меньшую защиту и не предлагают API. Конечно, с помощью STL можно выстрелить себе в ногу, но, по крайней мере, это сложнее.
Здесь, кажется, есть некоторая путаница относительно того, что векторы безопасности могут и не могут обеспечить. Не обращая внимания на использование итераторов, существует три основных способа доступа к элементам в векторе.
функция operator[] вектора - это не обеспечивает проверку границ и приведет к неопределенному поведению при ошибке границ, так же, как массив, если вы используете недопустимый индекс.
векторная функция at() - она обеспечивает проверку границ и вызывает исключение, если используется недопустимый индекс, с небольшими затратами на производительность
оператор C++ [] для базового массива вектора - он не обеспечивает проверку границ, но обеспечивает максимально возможную скорость доступа.
Массивы не выполняют связанную проверку. Следовательно, они очень уязвимы для ошибок проверки границ, которые трудно обнаружить.
Примечание: следующий код имеет ошибку программирования.
int Data[] = { 1, 2, 3, 4 };
int Sum = 0;
for (int i = 0; i <= 4; ++i) Sum += Data[i];
Используя такие массивы, вы не получите исключение, которое поможет вам найти ошибку; только неверный результат.
Массивы не знают своего собственного размера, тогда как vector
определяет begin
а также end
методы доступа к его элементам. С массивами вы всегда должны полагаться на арифметику указателей (а так как они являются ничем иным, как указателями, вы можете случайно привести их)
Массивы C++ не выполняют проверку границ ни при вставке, ни при чтении, и довольно легко случайно получить доступ к элементам за пределами границ массива.
С точки зрения ОО, вектор также имеет больше знаний о себе и, таким образом, может заниматься своим домашним хозяйством.
В вашем примере есть статический массив с фиксированным количеством элементов; в зависимости от вашего алгоритма, это может быть так же безопасно, как вектор с фиксированным количеством элементов.
Однако, как правило, когда вы хотите динамически выделить массив элементов, вектор намного проще, а также позволяет делать меньше ошибок. Каждый раз, когда вам нужно подумать, есть вероятность ошибки, которая может быть использована.