0

I am trying to learn error trapping using the C++ commands try, throw, and catch.

The problem I seem to be encountering is when I use new to declare an array. When the program throws an exception, don't I need to delete those arrays to prevent a memory leak? I am thinking yes. But, when I try to compile code with the delete commands in the catch, I get a variable out of scope error from the compiler.

I am doing something like this:

int function ()
{
try {
 string * files = new string[dirsize];
 code;
 if (something bad happens)
   throw ("error");
 more code;
 delete[] files;
 return 1;
 } // closing try section
catch (const char *msg)
 {
  delete[] files; // this is where I get the compiler error
  cout << msg;
 } // end catch
} //close function 

Now, I know I could put the delete command here, as:

if (something bad happens) {
  delete[] files;
  throw ("error");
  }

But, doing it this way would seem to defeat the purpose of the throw command. I could just as easily structure the program with and if{}else{} combination and get a similar outcome without using the try, throw, catch commands.

So, I feel that I am missing something about the purpose, or proper use, of try, throw and catch.

Yes, I know I could avoid some of this by using vector, or some other container, but that would still not educate me about try, throw and catch.

What am I missing?

Thanks.

3
Contributors
3
Replies
34
Views
2 Months
Discussion Span
Last Post by Thomas_36
1

I will try my best to keep this as simple as possible, hope I can be of help:

The problem I seem to be encountering is when I use new to declare an array.

Allocating memory via new can throw a std::bad_alloc when there isn't enough memory to use.

When the program throws an exception, don't I need to delete those arrays to prevent a memory leak?

No, because the assignment never happened in the first place.
string * files = new string[dirsize];
The exception is thrown when just new string[dirsize] is called. When an exception
is thrown inside a try block, the program jumps directly at the beggining of the catch block, so the assignment operator = is never called. Because of this, you don't
have to call delete[].

When I try to compile code with the delete commands in the catch, I get a variable out of scope error from the compiler.

Indeed, and that's because the string * files is visible only at the level of the catch scope. This is unrelated to exceptions or try/catch blocks and it's the same as doing this:

int main()
{
    {
        int a;

        // a lifetime ends here
        // because it reached the
        // end of the scope (block)
    }
    {
        // so this will result in a
        // compiler error
        a = 5; 
    }
}

Here's an example of handling the exception:

#include <iostream>
#include <string>

void function()
{
    const int dirsize = 1000000000;

    try
    {
        std::string * files = new std::string[dirsize];

        files[0] = "this will not execute";
        files[123124125125] = "neither this";
    }
    catch (const std::exception & e)
    {
        std::cout << e.what() << std::endl;
    }
}

int main()
{
    function();

    std::cout << "The program continued safely after function() has finished.";
}

Usually, in a real world scenario, it's better to handle this by avoiding a std::bad_alloc exception. An alternative can be:

#include <iostream>
#include <string>

void function()
{
    const int dirsize = 1000000000;

    std::string * files = new (std::nothrow) std::string[dirsize];

    if (files == nullptr)
        std::cout << "Failed allocating memory for 'files'.\n";
    else
        files[0] = "This works if 'dirsize' has a valid value.\n";
}

int main()
{
    function();

    std::cout << "The program continued safely after function() has finished.";
}

If the new fails, then the pointer 'files' becomes nullptr.
I haven't really used C++ in a long time so someone more experienced can surely chime in with more suggestions.

2

Coller pretty much has it nailed. If you have a try/catch block that fails, then allocated code that was allocated before the try/catch block will no longer be valid.

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.