Проблема заключается в том, что она печатает счет как «11», даже если результат состоит из 10 чисел в массиве.
Если я правильно понял это, вы получаете доступ к 10-му индексу массива размера 10, который является неопределенным поведением, потому что он находится за пределами доступа.
Если вы используете C++ 03, вы можете избежать использования необработанных массивов и предпочесть std::vector
. std::vector
автоматически обрабатывает память для вас, а функция-член at()
будет генерировать исключение, если вы попытаетесь предоставить индекс за пределами границ. Будьте уверены, что operator[]
не обеспечивает проверку границ.
В C++ 11 вы можете использовать std::array
. Подобно std::vector
, он имеет at()
, который обеспечивает проверку границ и operator[]
, что нет. Функция non-member std::get
обеспечивает проверку границ времени компиляции. Вот пример:
std::array<int, 5> arr { 1, 2, 3, 4, 5 };
std::get<6>(arr);
// error: static assertion failed: index is out of bounds
arr.at(6);
// terminate called after throwing an instance of 'std::out_of_range'
// what(): array::at: __n (which is 6) >= _Nm (which is 5)
Если вы застряли с сырыми массивами, ваш компилятор может прийти с диагностикой или инструментов, которые помогают поймать вне границ ошибок, таких как непредсказуемое поведение LLVM в дезинфицирующее (который был портирован на НКУ) и Valgrind (который сообщает об ошибках памяти) Вот пример Clang дает предупреждение выхода из ограничений:.
int arr[5] = { 1, 2, 3, 4, 5 };
arr[6];
// warning: array index 6 is past the end of the array (which contains 5 elements) [-Warray-bounds]
и сообщение, которое вы получите, если вы запустите его с -fsanitize=address,undefined
:
runtime error: index 6 out of bounds for type 'int [5]'
НКУ ловли неопределенное поведение в цикле:
for (int i = 0; i < 6; ++i)
std::cout << arr[i];
// warning: iteration 5u invokes undefined behavior [-Waggressive-loop-optimizations]
Это хороший аргумент для использования -Wall -Wextra -pedantic
, которые работают для обоих компиляторов, хотя имейте в виду, что точная диагностика вы получаете отличаться, поэтому всегда проверить свой код с кратному инструменты.
Итак, вы в основном пытаетесь добавить проверку границ в примитивный массив? –
Да, это был бы один из способов сказать это. –
Поскольку вы используете C++, предпочитаете использовать 'std :: array' или' std :: vector'. Функция 'at()' member предоставляет проверку границ времени выполнения, в то время как 'std :: get' обеспечивает проверку границ сеансов. В противном случае рассмотрим использование инструмента статического анализа или clang и gcc '-fsanitize = undefined'. GCC также может выходить за пределы доступа с помощью предупреждения. –