简体   繁体   中英

Overflow error when using C++ std::cin, has strange value inside variable (C++11)

For a C++ program, I've implemented 2 functions:

  1. Make1DArray that takes array size as input and creates a 1D array of that size
  2. Make2DArray that takes size of row and column and creates a 2D array of the given row and column sizes

The main function looks like this:

int main()
{
    cout << "enter 1d array length: ";
    int x;
    cin >> x;
    Make1DArray(x);

    cout << "enter 2d array row size: ";
    int nrows, ncols;
    cin >> nrows;
    cout << "enter 2d array col size: ";
    cin >> ncols;
    Make2DArray(nrows, ncols);

    return 0;
}

When I input x = 10000000000 (10^10), the program outputs does not run the second function and asks for input. The message outputs look like this:

enter 1d array length: 100000000000
enter 2d array row size: enter 2d array col size: 

So I checked the values for x, nrow, and ncol and the values were this:

  • x = 2147483647
  • nrows = 0
  • ncols = 32767

I googled a bit and found out that when an overflow error happens, cin would assign x the closest value. For nrows I understand it might get 0, as an error happened.

What I don't get is why the third variable, ncols is assigned value 32767. I did find out that 32767 is the max value of a short int but I don't know why the variable ncols would get this value.

Could anyone explain me this? Thanks!

ETA: I wasn't sure if I should add the two functions because they're really simple but just in case, they look like this:

void Make1DArray(int arrSize) {
    int *arr;
    arr = (int *)malloc(arrSize * sizeof(int));
    for (int i = 0; i < arrSize; i++)
    {
        arr[i] = i;
    }
}

void Make2DArray(int nrows, int ncols) {
    int **arr = (int **)malloc(nrows * sizeof(int *));
    for (int i = 0; i < nrows; i++)
        arr[i] = (int *)malloc(ncols * sizeof(int));
    int count;
    for (int i = 0; i < nrows; i++)
        for (int j = 0; j < ncols; j++)
        {
            arr[i][j] = ++count;
        }
}

The problem

THe problem is that the first overflow sets the failbit due to the value overflow. The subsequent readings are not performed, leaving nrows and ncols in an undefined state. If you'd initialize theses variables, you'll notice that they wouldn't change.

Solution

  1. Do not use int for holding the size but size_t instead. This should work with your example figures on most compilers.

  2. If you want your code to be bullet proof, check the state on cin to see if input was valid and handle any errors if necessary (including cin.clear() to clear the fail state before resuming reading).

  3. Not related: in the code of your functions (which leak memory by the way), iterate on a size_t as well. And avoid malloc() : in C++ prefer new for dynamically creating objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM