Search code examples
c++iostream

Infinite loop when trying to read an int greater than INT_MAX


I was writing some C++ code, to figure out the internal representation of integers. But I stumbled upon a weird bug, and I can't seem to reason about the cause of this issue.

The code is quite simple. it asks for a user input (I, LI, or SI).

LI and SI gives the representation of largest and smallest integers respectively. 'I' needs an integer input, whose representation the user wants to know.

Everything works perfect until I gave the input as,

I 2147483648

Now this is one greater than the largest integer in C++ (2147483647).

I expected the output to be 7FFFFFFF, which is the output for 2147483647 and ask for the next input.

But instead, this started an infinite loop, giving the output as:

7FFFFFFF
7FFFFFFF
7FFFFFFF
...

What is the the cause of this infinite loop?

#include <iostream>
#include <limits>
#include <map>
#include <string>
#include <unistd.h>
using namespace std;

const int intMax = numeric_limits<int>::max();
const int intMin = numeric_limits<int>::min();
int num;

void createMap(map<string, char> *um){

    (*um)["0000"] = '0';
    (*um)["0001"] = '1';
    (*um)["0010"] = '2';
    (*um)["0011"] = '3';
    (*um)["0100"] = '4';
    (*um)["0101"] = '5';
    (*um)["0110"] = '6';
    (*um)["0111"] = '7';
    (*um)["1000"] = '8';
    (*um)["1001"] = '9';
    (*um)["1010"] = 'A';
    (*um)["1011"] = 'B';
    (*um)["1100"] = 'C';
    (*um)["1101"] = 'D';
    (*um)["1110"] = 'E';
    (*um)["1111"] = 'F';
}

string convertBinToHex(string bin){

    int l = bin.size();
    map<string, char> bin_hex_map;
    createMap(&bin_hex_map);

    int i = 0;
    string hex = "";

    while(i < bin.size()){
        hex += bin_hex_map[bin.substr(i, 4)];
        i += 4;
    }
    return hex;
}

void printHex(int num){

    int *var_ptr;
    var_ptr = &num;
    string bin = "";

    for (int i=31; i>=0; i--) {
        bin += to_string((*var_ptr >> i) & 1);
    }
    // cout << bin << endl;
    cout << convertBinToHex(bin) << endl;
}

int main(){

    string input = "";
    cout << "Enter I or LI or SI or Q" << endl;
    // cin >> input;
    while(input != "Q"){
        cin >> input;
        if(input == "LI"){
            cout << intMax << " ";
            printHex(intMax);
        }
        else if(input == "SI"){
            cout << intMin << " ";
            printHex(intMin);
        }
        else if(input == "I"){
            cin >> num;
            printHex(num);
            // sleep(2);
            // cout << "What is going on ?" << endl;
        }
        else
            break;
    }
    return 0;
}

Solution

  • The problem isn't the integer representation. It's that the conversion of the input fails, which means it will still be left in the input buffer, leading to your infinite loop reading the exact same data over and over again.

    You need to check if the input succeeded or not, and if it failed you need to clear the buffer as well as the error flags:

    if (!(cin >> num))
    {
        // Error, failed to parse the input
    
        // First clear the error status flags
        cin.clear();
    
        // Then remove the current line of input from the buffer
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }
    else
    {
        // Input okay, use it...
    }
    

    Since it's a lot to write for each input, I suggest you move it out to a function that you call to get input.