1

How to handle std::bad_alloc exception in this function:

std::string GetString()
{
    std::string str;
    return str;
}

Since any stl constructor can throw bad_alloc, we've to do like this:

std::string GetString()
{
    try
    {
        std::string str;
        return str;
    }
    catch(std::bad_alloc&)
    {
        return ""; // Constructs temporary std::string and returns. Could throw !
    }
}

Again catch block is still not safe.

I just want to make this function exception proof.

6
  • What do you think you are achieving? If you get a bad_alloc, hiding it isn't doing anyone any favours. That said, constructing a completely empty string will not do an allocation, though I'd have to double check if that is guaranteed. Commented Mar 13, 2015 at 11:45
  • It's a kind of function in a library. Just trying to make library full-proof. and robust Ideally yes, it should have just a pointer on stack. So no no need to put c'tor in try block is what I feel Not sure although. Commented Mar 13, 2015 at 11:50
  • But why do you think it is important for your library to not propagate bad_alloc? The user will get back a string that they think is properly populated, but is not. Then they will get bad_alloc the moment they try to copy it, add to it, whatever. Commented Mar 13, 2015 at 11:54
  • 2
    If something went wrong in your library and it is unable to function normally, you should inform the user of your library that happened. Commented Mar 13, 2015 at 11:55
  • 1
    @Atul No, I am not saying that is what you should do. I might say that, once you have told us why you think you should be catching the exception in the first place. Then I can offer an opinion on whether that is right or wrong. There may be cases where what you are trying to do is correct. Probably, this is not one of them, but we don't know yet. Commented Mar 13, 2015 at 12:06

4 Answers 4

2

Although, (i think) it is not guaranteed by the standard, most (maybe all) std::string implementations don't allocate memory for an empty/short string (as mentioned by @BoBTFish). So your solution is as "exception proof", as it gets. I'd just suggest, to actually return a default constructed string instead of "".

However, the basic question you should ask yourself is if bad_alloc is something that you expect because you are potentially trying to construct a very big string or if it actually indicates, that your system completely ran out of memory:

If allocation fails, because you try to create a string of a few million characters, then constructing a shorter/empty error string will probably not thorw another exception an can be seen as proper form of error handling.

If it fails, because your program/system ran completely out of memory, you cannot deal with it locally (you e.g. cannot free any other memory) and therefore you probably also should not try to hide that error, because it will certainly come up again shortly after. So while returning an empty or short string would probably still work, I see no reason to catch that exception inside your function in the first place.

Sign up to request clarification or add additional context in comments.

4 Comments

I've seen bad_alloc on small strings plenty of times. Usually because we had a memory leak or something, but still. This is about guarantees, not likelihood.
no point in using a try catch block at all I believe that is my answer. Doesn't matter how much memory it tries to allocate and available. But I am just trying to write perfect and correct code which should go by standards.
if bad_alloc is something, that you expect - quite good. Maybe here should be added that this exception has a very high probability to be caused by the function you implement.
@BoBTFish: What I wanted to say is, that it only makes sense to handle a bad_alloc exception internally, if that exception happens because your function tries to create an unreasonably big string in the first place. If it is threown, because, your system actually ran out of memory, there is no use to block that exception in the frist place.
1

Try to follow this guideline: Only catch an exception if you can deal with its fundamental cause. Suppressing the exception is not solving the underlying problem that the exception has exposed.

To answer your question; there is nothing your function can do about the reason std::bad_alloc was thrown. Another function higher up the call stack might be able to do something, if you suppress the exception you make this impossible.

Comments

0

As a general rule, never catch an exception unless you know what to do with it.

Also, a program that crashes because of a non-caught exception is easier to debug than a program that crashes after it tries to resolve an exception

In the case you shown, if creating an empty string is a cause for bad_alloc then also returning "" will probably cause another bad_alloc (another empty string is implicitly created).

There are very few situations where you can resolve a bad_alloc: for instance if you know that you are caching a lot of data then you can free the cached data and retry the allocation.

1 Comment

Just a detail: some std::string implementation may create an empty strings without allocating memory on the heap.
0

Never catch exceptions that are not semantically related to the implementation of your function. Else you will end in catching std::exception in every function, which is obviously nonsense.

I just want to make this function exception proof.

It's impossible to create a std::string and to guarantee not to throw bad_alloc.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.