-1

I have a C++ simple queue console application, first display three main choices and ask user to choose: 1 enqueue, 2 dequeue, 3 exit. When user selects 1, it calls enqueue function and prompt user for input and then do the rest. The program is working fine when input is less than or equal to the max integer (2^31 − 1). When input is greater than the max int, the program goes to an infinite loop of displaying the three main choices. My question is that why the catch bad_alloc did not work when a greater-than-max int entered? Do you have any suggestions for how to handle this kind of memory exception? The following code is the enqueue function:

void Queue::enqueue()
{
    int data;
    node *temp = new node;

    try
    {
        cout << "Enter the data to enqueue: ";
        cin >> data;

        temp->info = data;
        temp->next = NULL;

        if (front == NULL) front = temp;
        else rear->next = temp;

        rear = temp;
    }
    catch (bad_alloc)
    {
       cout << "Ran out of memory!" << endl;
    }
}
  • 1
    What operation in the code you show should throw a `bad_alloc`? If you are talking about the `new` operation then it needs to be in the try block. – NathanOliver Apr 11 '16 at 18:55
  • Since the infinite loop is in code that you haven't shown, it's impossible to say what causes it. – Pete Becker Apr 11 '16 at 18:56
  • Shouldn't _`node *temp = new node;`_ go inside the `try` block to catch a `bad_alloc` exception? – πάντα ῥεῖ Apr 11 '16 at 18:59
  • *Check for failure on your IO calls*. Your invoke of `cin >> data` is completely unchecked. Entering a value larger than `INT_MAX` will *fail*. Once that happens, you'll (a) insert junk into your queue, then (b) return to the caller with an input stream still in fail-state. No doubt there you're performing more (unchecked) input that immediately fails because the stream is still in fail-state. Then you previous "choose-enqueue" choice is retained, comes back to this code, and the cycle repeats ad-infinitum (until complete virtual memory exhaustion), all because the IO was never checked. – WhozCraig Apr 11 '16 at 19:03
  • @WhozCraig, thank you for your reply. Yes, I understand that cin >> data will cause problem if it is unchecked. But I thought the catch block is there to catch this issue. This is a homework, instructor want us to use try catch(bad_alloc), if I check the input first, then catch block code will never be executed. – user3279790 Apr 11 '16 at 21:31
  • @user3279790 You *can* enable exceptions on `std::cin` via [`std::ios::exceptions()`](http://en.cppreference.com/w/cpp/io/basic_ios/exceptions). You will want to catch `std::ios::failure const&` in addition to your `std::bad_alloc const&` if that's the road you're going down. And it doesn't change the fact that the error state still needs to be cleared (and likely the remainder of the current input line fully consumed and thrown out). – WhozCraig Apr 11 '16 at 21:58

1 Answers1

1

My question is that why the catch bad_alloc did not work when a greater-than-max int entered?

That's because the only instruction that may throw a bad_alloc exception is

node *temp = new node;

which actually appears outside of your try/catch block.


To catch bad_alloc exceptions rewrite your code as

void Queue::enqueue()
{
    int data;        

    try
    {
        node *temp = new node; // <<< Try allocation
        cout << "Enter the data to enqueue: ";
        cin >> data;

        temp->info = data;
        temp->next = NULL;

        if (front == NULL) front = temp;
        else rear->next = temp;

        rear = temp;
    }
    catch (const bad_alloc& ex)
    {
       cout << ex.what() << std::endl << "Ran out of memory!" << endl;
    }
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • I tried the code above, it did not work. the exception should coming from cin >> data for a larger int input not node *temp = new node – user3279790 Apr 11 '16 at 21:21