Search code examples
c++arraysfor-loopdo-whilestack-smash

stack smashing terminates program


I am learning C++ and was given the task to create a program that allows user to modify an array with 10 integers in it. if user gives an index out of range program will exit. Program works with negative numbers and all numbers with in the range. when I enter a number like 10 which is above the range I get:

* stack smashing detected *: terminated

I am new to this and any help will be much appreciated.

#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;
}

When I run the program, I get this:

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

Solution

  • You are accessing memory which is not part of your array hence that error message. You should first validate the index before assigning the value using subscript operator [].

    Here's your code snippet (commented) that caused the problem:

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

    There are a number of things that I'd like to point out:

    For initialization with the same value, you don't need a loop because std::array::fill() member function does exactly that.

    Example:

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

    You are using std::array that means you are at least using C++11. So, for array traversals, you can use C++11's range-for loop like this:

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

    You might want to look at auto specifier if you're not already familiar with it.

    I don't know your reasoning for using do-while loop here. You can use a simple while infinite loop (for learning purposes) breaking it on an invalid index input using if-else for validating index before assignment.

    For example:

    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;
        }
    }
    

    Please do take a look at std::array::at() member function which performs bounds checking and throws an exception on violation.


    I'm not sure what you're doing with this part because braces around std::cout are redundant here:

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

    Maybe, you're confusing do-while with while loop.


    Please don't forget to format your code in future. Use your IDE's code formatting features or you can use any online code formatting sites too (e.g. http://format.krzaq.cc/) while posting your code on SO. Thanks!