разрушение стека завершает программу - PullRequest
0 голосов
/ 15 сентября 2018

Я изучаю 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

1 Ответ

0 голосов
/ 15 сентября 2018

Вы обращаетесь к памяти, которая не является частью вашего массива, следовательно, это сообщение об ошибке.Вы должны сначала проверить индекс, прежде чем присваивать значение, используя оператор индекса [].

Вот ваш фрагмент кода ( с комментариями ), который вызвал проблему:

cin >> v;
myData[i] = v; // Direct assignment without validating i
               // i needs to be validated before this assignment

Есть несколько вещей, на которые я бы хотел обратить внимание:

Для инициализации с тем же значением вам не нужен цикл, потому что std :: array :: fill () функция-член делает именно это.

Пример:

std::array<int, 10> data;
data.fill( 1 );

Вы используете std::array, что означает, что вы по крайней мере используете C ++ 11.Таким образом, для обхода массива вы можете использовать цикл C ++ 11 range-for следующим образом:

for ( const auto& i : data )
{
    std::cout << i << ' ';
}

Возможно, вы захотите посмотреть auto спецификатор , еслиВы еще не знакомы с ним.

Я не знаю, почему вы используете здесь цикл 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() функцию-члена, которая выполняет проверку границ и выдает исключение при нарушении.


Iя не уверен, что вы делаете с этой частью, потому что скобки вокруг std::cout здесь избыточны:

while(i >= 0  && i < myData.size());    // do-while ends here
{
  cout << endl <<"Index out of range: Exit "<< endl;
}

Возможно, вы путаете do-while с while loop.


Пожалуйста, не забудьте отформатировать свой код в будущем.Используйте функции форматирования кода в вашей среде IDE или вы также можете использовать любые онлайн-сайты форматирования кода (например, http://format.krzaq.cc/) при публикации кода на SO. Спасибо!

...