1

I'm a new C++ programmer, so I never wrote C++ code for anything older than C++11. I was reading Scott Meyers "Effective C++, 2nd Edition" (I know it is old, but I think it still has some valid points).

In the book, according to "Item 7", new can throw exceptions which should be handled.

Can new still throw exceptions?

Should I be prepared about exceptions that could be thrown by a smart pointer or new?

Braiam
  • 1
  • 11
  • 47
  • 78
Blank
  • 23
  • 7
  • When using smart pointers, avoid using `new`. Instead use the `make_unique` and `make_shared` functions. They handle the non-trivial clean-up should they fail to construct the instance or anything else goes wrong. – user4581301 May 17 '22 at 18:48
  • You should not use `new` directly anyway in almost all cases, partially exactly because it is hard to make its use exception-safe. In contrast to smart pointers it does not guarantee that `new`ed objects are destroyed and memory is freed automatically when an exception occurs (outside the `new` expression itself). – user17732522 May 17 '22 at 18:49
  • @user4581301 the question was specifically about the use of new; you don't know his application case. There are situations where smart pointers aren't appropriate/possible – Inigo Selwood May 17 '22 at 18:50
  • 2
    Herb Sutter and Scott Meyers also have pointed out that out of memory situation is pretty much an irrecoverable situation. And, even worse — with modern operating systems — they can overallocate memory and potentially allow a program to ask for a large block of memory, but when the program tries to use it at some point it'll fault the program because the memory wasn't *really* available. – Eljay May 17 '22 at 18:52
  • 1
    Also note that being prepared for exceptions to occur does not mean that you are supposed to put `try`/`catch` around every use of `new`. You only need to catch exceptions where it makes sense for your program to recover from failure. (As mentioned above for `std::bad_alloc` from `new` that often is nowhere.) You should however make sure that the code is exception-safe and doesn't leak any memory or other resources if an exception occurs. – user17732522 May 17 '22 at 18:52
  • @InigoSelwood the comment is simply meant to address the last line of the question. If it was a complete thought and an answer, I would have written an answer. Though on second reading, it's no so useful a comment as I thought. The asker doesn't seem to be asking about `new` with smart pointers. I should have paid more attention to the or. – user4581301 May 17 '22 at 18:55
  • @Eljay Please define `fault the program`. My understanding is that desktop OS's don't overcommit _virtual_ memory, so they will always be able to come good on their promises ... eventually. Also, `std::bad_alloc` might result from exceeding some kind of quota, although it's probably still not recoverable. – Paul Sanders May 17 '22 at 18:58
  • @blank you don't need to tag all those C++ language versions so I removed them. Those tags are for when you're interested in (or limited to) a _specific_ version (or versions). – Paul Sanders May 17 '22 at 19:23
  • @PaulSanders • My understanding — and experience — is that desktop OS's do overcommit virtual memory, and could fault the program if they are unable to provide the memory promised. Part of the situation can be blamed on programs which are "bad citizens" because they over-request heap memory as a common practice. In aggregate, memory becomes overcommitted which isn't a problem normally, until in the rare situation (in practice) where it becomes a problem. But that'll be long after the `new` had seemingly succeeded. – Eljay May 17 '22 at 21:14
  • @Eljay Seems to depend on the platform (which I kinda suspected): https://superuser.com/questions/1194263/will-microsoft-windows-10-overcommit-memory. I have to say, I prefer the Windows approach. – Paul Sanders May 17 '22 at 21:56
  • @Eljay ... and sorry to question your expertise, especially in such a high-handed manner. You clearly know what you're talking about. – Paul Sanders May 18 '22 at 06:40
  • 1
    @PaulSanders • It's okay. This site is a forum were we can share our knowledge to help one another. None of us (and I'm including myself!) know everything. Sometimes I find out I'm mistaken, and I learn... that's a good thing. – Eljay May 18 '22 at 13:17
  • @Eljay I agree, and thank you for your kindness. – Paul Sanders May 18 '22 at 14:04

1 Answers1

1

Yes, on allocation new can throw a bad_alloc exception.

That is, unless you pass const std::nothrow_t& as the second parameter, where you'll be guaranteed a return value of nullptr

See details here

Inigo Selwood
  • 822
  • 9
  • 20
  • Can smart pointers throw an exception? – Blank May 17 '22 at 19:00
  • @Blank yes. Even with a smart pointer things can go wrong and need contextual information not available to the constructor of the class being constructed (for example, the constructor needs to open a file and can't. What to do then?) or the aforementioned `bad_alloc`. Smart pointer will make sure the allocation and the smart pointer itself are properly cleaned up, but you will still have to deal with the thrown exception one way or another. – user4581301 May 17 '22 at 19:09
  • 2
    Notoriously `new` with `nothrow` will still throw if the new objects' constructor throws which makes it significantly less useful than expected. – François Andrieux May 17 '22 at 21:38
  • @FrançoisAndrieux Interesting, but perhaps not totally unexpected. Adding code to handle such a (potential) exception would significantly compexify `nothrow` `new` and (more importantly) add overhead. – Paul Sanders May 17 '22 at 22:50