Я изучаю C ++, и мне было поручено создать программу, которая позволяет пользователю изменять массив с 10 целыми числами. если пользователь выдаст индекс вне диапазона, программа завершится. Программа работает с отрицательными числами и со всеми числами в диапазоне. когда я ввожу число как 10, которое выше диапазона, я получаю:
* Обнаружено разрушение стека *: прекращено
Я новичок в этом, и любая помощь будет высоко ценится.
#include <iostream>
#include <array>
using namespace std;
int main()
{
array<int, 10> myData; // creates array size 10
int i = 0;
int v = 0;
for (unsigned int n = 0; n < myData.size(); n++) // makes all elements 1
{
myData[n] = 1;
}
do
{
for (unsigned int a = 0; a < myData.size(); a++)
{
cout << myData[a] << " ";
}
cout << endl << "Input index: ";
cin >> i;
cout << endl << "Input value: ";
cin >> v;
myData[i] = v;
} while (i >= 0 && i < myData.size());
{
cout << endl << "Index out of range: Exit " << endl;
}
return 0;
}
Когда я запускаю программу, я получаю это:
1 1 1 1 1 1 1 1 1 1
Input index: 10
Input value: 4
Index out of range: Exit
*** stack smashing detected ***: <unknown> terminated
[1] 56 abort (core dumped) ./edit
Вы обращаетесь к памяти, которая не является частью вашего массива, следовательно, это сообщение об ошибке. Вы должны сначала проверить индекс, прежде чем присваивать значение с помощью оператора индекса [].
Вот ваш фрагмент кода (прокомментировал) что вызвало проблему:
cin >> v;
myData[i] = v; // Direct assignment without validating i
// i needs to be validated before this assignment
Есть несколько вещей, на которые я хотел бы указать:
Для инициализации с тем же значением вам не нужен цикл, потому что станд :: массив :: заливка () функция-член делает именно это.
Пример:
std::array<int, 10> data;
data.fill( 1 );
Ты используешь std::array
это означает, что вы, по крайней мере, используете C ++ 11. Таким образом, для обхода массива вы можете использовать C ++ 11 Диапазон-для цикл как это:
for ( const auto& i : data )
{
std::cout << i << ' ';
}
Вы можете посмотреть на автоматический спецификатор если вы еще не знакомы с этим.
Я не знаю твои аргументы в пользу использования do-while
Цикл здесь. Вы можете использовать простой while
бесконечный цикл (в учебных целях) разбить его на неверный ввод индекса, используя if-else
для проверки индекса перед присвоением.
Например:
while ( true )
{
// Print array here...
std::cin >> index;
if ( /* index is out of bounds */ )
{
std::cerr << "ERROR: Out-of-range index!\n";
break; // Exit from loop here on invalid index
}
else
{
std::cin >> value;
data[ index ] = value;
}
}
Пожалуйста, взгляните на std::array::at()
функция-член, которая выполняет проверку границ и создает исключение при нарушении.
Я не уверен, что ты делаешь с этой частью, потому что std::cout
здесь избыточны:
while(i >= 0 && i < myData.size()); // do-while ends here
{
cout << endl <<"Index out of range: Exit "<< endl;
}
Может быть, вы путаете do-while
с while
петля.
Пожалуйста, не забудьте отформатировать свой код в будущем. Используйте функции форматирования кода в вашей среде IDE или вы также можете использовать любые онлайн-сайты форматирования кода (например, http://format.krzaq.cc/) при размещении вашего кода на SO. Спасибо!
Других решений пока нет …